Merge tag 'ubi-updates-for-2026.10-rc1' of https://source.denx.de/u-boot/custodians/u-boot-ubi
ubi updates for 2026.10-rc1
- fs: ubifs: fix ubifs_finddir() from Patrick
Fixes: 0cab29ff46 ("fs: ubifs: Fix and rework error handling in ubifs_finddir")
fix test -e
- cmd: ubi: rework from Weijie
- env: ubi: add support to create environment volume if it does not exist
- cmd: ubi: allow creating volume with all free spaces in ubi_create_vol
- cmd: ubi: export more APIs to public
- cmd: ubi: reorganize command messages
- cmd: ubi: change all positive error return value to negative
- cmd: ubi: change the type of parameter dynamic to bool
- cmd: ubifs: mark string parameters with const
- cmd: ubi: use void * for buf parameter in ubi_volume_read
- cmd: ubi: mark read-only function parameters with const
- ubi: remove unnecessary extern directive from function prototypes
This commit is contained in:
@@ -39,7 +39,7 @@ static struct ubi_device *ubi;
|
||||
#include <ubifs_uboot.h>
|
||||
#endif
|
||||
|
||||
static void display_volume_info(struct ubi_device *ubi)
|
||||
static void display_volume_info(const struct ubi_device *ubi)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -50,7 +50,7 @@ static void display_volume_info(struct ubi_device *ubi)
|
||||
}
|
||||
}
|
||||
|
||||
static void display_ubi_info(struct ubi_device *ubi)
|
||||
static void display_ubi_info(const struct ubi_device *ubi)
|
||||
{
|
||||
ubi_msg("MTD device name: \"%s\"", ubi->mtd->name);
|
||||
ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20);
|
||||
@@ -149,12 +149,12 @@ static int ubi_list(const char *var, int numeric)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ubi_check_volumename(const struct ubi_volume *vol, char *name)
|
||||
static int ubi_check_volumename(const struct ubi_volume *vol, const char *name)
|
||||
{
|
||||
return strcmp(vol->name, name);
|
||||
}
|
||||
|
||||
static int ubi_check(char *name)
|
||||
static int ubi_check(const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -172,7 +172,7 @@ static int ubi_check(char *name)
|
||||
static int verify_mkvol_req(const struct ubi_device *ubi,
|
||||
const struct ubi_mkvol_req *req)
|
||||
{
|
||||
int n, err = EINVAL;
|
||||
int n, err = -EINVAL;
|
||||
|
||||
if (req->bytes < 0 || req->alignment < 0 || req->vol_type < 0 ||
|
||||
req->name_len < 0)
|
||||
@@ -187,7 +187,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
|
||||
|
||||
if (req->bytes == 0) {
|
||||
printf("No space left in UBI device!\n");
|
||||
err = ENOMEM;
|
||||
err = -ENOMEM;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi,
|
||||
|
||||
if (req->name_len > UBI_VOL_NAME_MAX) {
|
||||
printf("Name too long!\n");
|
||||
err = ENAMETOOLONG;
|
||||
err = -ENAMETOOLONG;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
@@ -213,8 +213,8 @@ bad:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
|
||||
bool skipcheck)
|
||||
int ubi_create_vol(const char *volume, int64_t size, bool dynamic, int vol_id,
|
||||
bool skipcheck)
|
||||
{
|
||||
struct ubi_mkvol_req req;
|
||||
int err;
|
||||
@@ -226,7 +226,11 @@ static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
|
||||
|
||||
req.vol_id = vol_id;
|
||||
req.alignment = 1;
|
||||
req.bytes = size;
|
||||
|
||||
if (size < 0)
|
||||
req.bytes = ubi->avail_pebs * ubi->leb_size;
|
||||
else
|
||||
req.bytes = size;
|
||||
|
||||
strcpy(req.name, volume);
|
||||
req.name_len = strlen(volume);
|
||||
@@ -241,13 +245,12 @@ static int ubi_create_vol(char *volume, int64_t size, int dynamic, int vol_id,
|
||||
printf("verify_mkvol_req failed %d\n", err);
|
||||
return err;
|
||||
}
|
||||
printf("Creating %s volume %s of size %lld\n",
|
||||
dynamic ? "dynamic" : "static", volume, size);
|
||||
|
||||
/* Call real ubi create volume */
|
||||
return ubi_create_volume(ubi, &req);
|
||||
}
|
||||
|
||||
static struct ubi_volume *ubi_find_volume(char *volume)
|
||||
struct ubi_volume *ubi_find_volume(const char *volume)
|
||||
{
|
||||
struct ubi_volume *vol;
|
||||
int i;
|
||||
@@ -258,24 +261,26 @@ static struct ubi_volume *ubi_find_volume(char *volume)
|
||||
return vol;
|
||||
}
|
||||
|
||||
printf("Volume %s not found!\n", volume);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ubi_remove_vol(char *volume)
|
||||
static struct ubi_volume *ubi_require_volume(const char *volume)
|
||||
{
|
||||
struct ubi_volume *vol = ubi_find_volume(volume);
|
||||
|
||||
if (!vol)
|
||||
printf("Volume %s not found!\n", volume);
|
||||
|
||||
return vol;
|
||||
}
|
||||
|
||||
static int __ubi_remove_vol(struct ubi_volume *vol)
|
||||
{
|
||||
int err, reserved_pebs, i;
|
||||
struct ubi_volume *vol;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
if (vol == NULL)
|
||||
return ENODEV;
|
||||
|
||||
printf("Remove UBI volume %s (id %d)\n", vol->name, vol->vol_id);
|
||||
|
||||
if (ubi->ro_mode) {
|
||||
printf("It's read-only mode\n");
|
||||
err = EROFS;
|
||||
err = -EROFS;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
@@ -310,35 +315,40 @@ static int ubi_remove_vol(char *volume)
|
||||
|
||||
return 0;
|
||||
out_err:
|
||||
ubi_err(ubi, "cannot remove volume %s, error %d", volume, err);
|
||||
if (err < 0)
|
||||
err = -err;
|
||||
ubi_err(ubi, "cannot remove volume %s, error %d", vol->name, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ubi_rename_vol(char *oldname, char *newname)
|
||||
int ubi_remove_vol(const char *volume)
|
||||
{
|
||||
struct ubi_volume *vol;
|
||||
|
||||
vol = ubi_require_volume(volume);
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
|
||||
return __ubi_remove_vol(vol);
|
||||
}
|
||||
|
||||
static int ubi_rename_vol(const char *oldname, const char *newname)
|
||||
{
|
||||
struct ubi_volume *vol;
|
||||
struct ubi_rename_entry rename;
|
||||
struct ubi_volume_desc desc;
|
||||
struct list_head list;
|
||||
|
||||
vol = ubi_find_volume(oldname);
|
||||
if (!vol) {
|
||||
printf("%s: volume %s doesn't exist\n", __func__, oldname);
|
||||
return ENODEV;
|
||||
}
|
||||
vol = ubi_require_volume(oldname);
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
|
||||
if (!ubi_check(newname)) {
|
||||
printf("%s: volume %s already exist\n", __func__, newname);
|
||||
return EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
printf("Rename UBI volume %s to %s\n", oldname, newname);
|
||||
|
||||
if (ubi->ro_mode) {
|
||||
printf("%s: ubi device is in read-only mode\n", __func__);
|
||||
return EROFS;
|
||||
return -EROFS;
|
||||
}
|
||||
|
||||
rename.new_name_len = strlen(newname);
|
||||
@@ -354,24 +364,25 @@ static int ubi_rename_vol(char *oldname, char *newname)
|
||||
return ubi_rename_volumes(ubi, &list);
|
||||
}
|
||||
|
||||
static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
|
||||
static int ubi_volume_continue_write(const char *volume, const void *buf,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
struct ubi_volume *vol;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
vol = ubi_require_volume(volume);
|
||||
if (vol == NULL)
|
||||
return ENODEV;
|
||||
return -ENODEV;
|
||||
|
||||
if (!vol->updating) {
|
||||
printf("UBI volume update was not initiated\n");
|
||||
return EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = ubi_more_update_data(ubi, vol, buf, size);
|
||||
if (err < 0) {
|
||||
printf("Couldnt or partially wrote data\n");
|
||||
return -err;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
@@ -379,7 +390,7 @@ static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
|
||||
|
||||
err = ubi_check_volume(ubi, vol->vol_id);
|
||||
if (err < 0)
|
||||
return -err;
|
||||
return err;
|
||||
|
||||
if (err) {
|
||||
ubi_warn(ubi, "volume %d on UBI device %d is corrupt",
|
||||
@@ -394,27 +405,27 @@ static int ubi_volume_continue_write(char *volume, void *buf, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ubi_volume_begin_write(char *volume, void *buf, size_t size,
|
||||
size_t full_size)
|
||||
int ubi_volume_begin_write(const char *volume, const void *buf, size_t size,
|
||||
size_t full_size)
|
||||
{
|
||||
int err;
|
||||
int rsvd_bytes;
|
||||
struct ubi_volume *vol;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
vol = ubi_require_volume(volume);
|
||||
if (vol == NULL)
|
||||
return ENODEV;
|
||||
return -ENODEV;
|
||||
|
||||
rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
|
||||
if (size > rsvd_bytes) {
|
||||
printf("size > volume size! Aborting!\n");
|
||||
return EINVAL;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
err = ubi_start_update(ubi, vol, full_size);
|
||||
if (err < 0) {
|
||||
printf("Cannot start volume update\n");
|
||||
return -err;
|
||||
return err;
|
||||
}
|
||||
|
||||
/* The volume is just wiped out */
|
||||
@@ -424,8 +435,8 @@ int ubi_volume_begin_write(char *volume, void *buf, size_t size,
|
||||
return ubi_volume_continue_write(volume, buf, size);
|
||||
}
|
||||
|
||||
static int ubi_volume_offset_write(char *volume, void *buf, loff_t offset,
|
||||
size_t size)
|
||||
static int ubi_volume_offset_write(const char *volume, const void *buf,
|
||||
loff_t offset, size_t size)
|
||||
{
|
||||
int len, tbuf_size, ret;
|
||||
u64 lnum;
|
||||
@@ -433,7 +444,7 @@ static int ubi_volume_offset_write(char *volume, void *buf, loff_t offset,
|
||||
loff_t off = offset;
|
||||
void *tbuf;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
vol = ubi_require_volume(volume);
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
|
||||
@@ -487,7 +498,8 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size)
|
||||
int ubi_volume_write(const char *volume, const void *buf, loff_t offset,
|
||||
size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@@ -503,36 +515,28 @@ int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size)
|
||||
static int __ubi_volume_read(struct ubi_volume *vol, void *buf, loff_t offset,
|
||||
size_t size)
|
||||
{
|
||||
int err, lnum, off, len, tbuf_size;
|
||||
void *tbuf;
|
||||
unsigned long long tmp;
|
||||
struct ubi_volume *vol;
|
||||
loff_t offp = offset;
|
||||
size_t len_read;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
if (vol == NULL)
|
||||
return ENODEV;
|
||||
|
||||
if (vol->updating) {
|
||||
printf("updating");
|
||||
return EBUSY;
|
||||
return -EBUSY;
|
||||
}
|
||||
if (vol->upd_marker) {
|
||||
printf("damaged volume, update marker is set");
|
||||
return EBADF;
|
||||
return -EBADF;
|
||||
}
|
||||
if (offp == vol->used_bytes)
|
||||
return 0;
|
||||
|
||||
if (size == 0) {
|
||||
printf("No size specified -> Using max size (%lld)\n", vol->used_bytes);
|
||||
if (size == 0)
|
||||
size = vol->used_bytes;
|
||||
}
|
||||
|
||||
printf("Read %zu bytes from volume %s to %p\n", size, volume, buf);
|
||||
|
||||
if (vol->corrupted)
|
||||
printf("read from corrupted volume %d", vol->vol_id);
|
||||
@@ -545,7 +549,7 @@ int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size)
|
||||
tbuf = malloc_cache_aligned(tbuf_size);
|
||||
if (!tbuf) {
|
||||
printf("NO MEM\n");
|
||||
return ENOMEM;
|
||||
return -ENOMEM;
|
||||
}
|
||||
len = size > tbuf_size ? tbuf_size : size;
|
||||
|
||||
@@ -561,7 +565,6 @@ int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size)
|
||||
err = ubi_eba_read_leb(ubi, vol, lnum, tbuf, off, len, 0);
|
||||
if (err) {
|
||||
printf("read err %x\n", err);
|
||||
err = -err;
|
||||
break;
|
||||
}
|
||||
off += len;
|
||||
@@ -587,7 +590,19 @@ int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ubi_dev_scan(struct mtd_info *info, const char *vid_header_offset)
|
||||
int ubi_volume_read(const char *volume, void *buf, loff_t offset, size_t size)
|
||||
{
|
||||
struct ubi_volume *vol;
|
||||
|
||||
vol = ubi_require_volume(volume);
|
||||
if (!vol)
|
||||
return -ENODEV;
|
||||
|
||||
return __ubi_volume_read(vol, buf, offset, size);
|
||||
}
|
||||
|
||||
static int ubi_dev_scan(const struct mtd_info *info,
|
||||
const char *vid_header_offset)
|
||||
{
|
||||
char ubi_mtd_param_buffer[80];
|
||||
int err;
|
||||
@@ -600,28 +615,25 @@ static int ubi_dev_scan(struct mtd_info *info, const char *vid_header_offset)
|
||||
|
||||
err = ubi_mtd_param_parse(ubi_mtd_param_buffer, NULL);
|
||||
if (err)
|
||||
return -err;
|
||||
return err;
|
||||
|
||||
led_activity_blink();
|
||||
err = ubi_init();
|
||||
led_activity_off();
|
||||
if (err)
|
||||
return -err;
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ubi_set_skip_check(char *volume, bool skip_check)
|
||||
static int ubi_set_skip_check(const char *volume, bool skip_check)
|
||||
{
|
||||
struct ubi_vtbl_record vtbl_rec;
|
||||
struct ubi_volume *vol;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
vol = ubi_require_volume(volume);
|
||||
if (!vol)
|
||||
return ENODEV;
|
||||
|
||||
printf("%sing skip_check on volume %s\n",
|
||||
skip_check ? "Sett" : "Clear", volume);
|
||||
return -ENODEV;
|
||||
|
||||
vtbl_rec = ubi->vtbl[vol->vol_id];
|
||||
if (skip_check) {
|
||||
@@ -635,7 +647,7 @@ static int ubi_set_skip_check(char *volume, bool skip_check)
|
||||
return ubi_change_vtbl_record(ubi, vol->vol_id, &vtbl_rec);
|
||||
}
|
||||
|
||||
static int ubi_detach(void)
|
||||
int ubi_detach(void)
|
||||
{
|
||||
#ifdef CONFIG_CMD_UBIFS
|
||||
/*
|
||||
@@ -658,7 +670,7 @@ static int ubi_detach(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ubi_part(char *part_name, const char *vid_header_offset)
|
||||
int ubi_part(const char *part_name, const char *vid_header_offset)
|
||||
{
|
||||
struct mtd_info *mtd;
|
||||
int err;
|
||||
@@ -674,7 +686,7 @@ int ubi_part(char *part_name, const char *vid_header_offset)
|
||||
mtd = get_mtd_device_nm(part_name);
|
||||
if (IS_ERR(mtd)) {
|
||||
printf("Partition %s not found!\n", part_name);
|
||||
return 1;
|
||||
return -ENODEV;
|
||||
}
|
||||
put_mtd_device(mtd);
|
||||
|
||||
@@ -695,6 +707,8 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
int64_t size;
|
||||
ulong addr = 0;
|
||||
bool skipcheck = false;
|
||||
struct ubi_volume *vol;
|
||||
int ret;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
@@ -709,7 +723,7 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
if (argc == 2) {
|
||||
if (!ubi) {
|
||||
printf("Error, no UBI device selected!\n");
|
||||
return 1;
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
printf("Device %d: %s, MTD partition %s\n",
|
||||
@@ -723,12 +737,13 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
if (argc > 3)
|
||||
vid_header_offset = argv[3];
|
||||
|
||||
return ubi_part(argv[2], vid_header_offset);
|
||||
ret = ubi_part(argv[2], vid_header_offset);
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
}
|
||||
|
||||
if ((strcmp(argv[1], "part") != 0) && !ubi) {
|
||||
printf("Error, no UBI device selected!\n");
|
||||
return 1;
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "info") == 0) {
|
||||
@@ -758,11 +773,11 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
return ubi_check(argv[2]);
|
||||
|
||||
printf("Error, no volume name passed\n");
|
||||
return 1;
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "create", 6) == 0) {
|
||||
int dynamic = 1; /* default: dynamic volume */
|
||||
bool dynamic = true; /* default: dynamic volume */
|
||||
int id = UBI_VOL_NUM_AUTO;
|
||||
|
||||
/* Use maximum available size */
|
||||
@@ -783,10 +798,10 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
/* E.g., create volume size type */
|
||||
if (argc == 5) {
|
||||
if (strncmp(argv[4], "s", 1) == 0)
|
||||
dynamic = 0;
|
||||
dynamic = false;
|
||||
else if (strncmp(argv[4], "d", 1) != 0) {
|
||||
printf("Incorrect type\n");
|
||||
return 1;
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
argc--;
|
||||
}
|
||||
@@ -799,38 +814,80 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
/* Use maximum available size */
|
||||
if (!size) {
|
||||
size = (int64_t)ubi->avail_pebs * ubi->leb_size;
|
||||
printf("No size specified -> Using max size (%lld)\n", size);
|
||||
if (size)
|
||||
printf("No size specified -> Using max size (%lld)\n",
|
||||
size);
|
||||
}
|
||||
/* E.g., create volume */
|
||||
if (argc == 3) {
|
||||
return ubi_create_vol(argv[2], size, dynamic, id,
|
||||
skipcheck);
|
||||
ret = ubi_create_vol(argv[2], size, dynamic, id,
|
||||
skipcheck);
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
printf("Created %s volume %s of size %lld\n",
|
||||
dynamic ? "dynamic" : "static", argv[2], size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "remove", 6) == 0) {
|
||||
/* E.g., remove volume */
|
||||
if (argc == 3)
|
||||
return ubi_remove_vol(argv[2]);
|
||||
if (argc == 3) {
|
||||
int vol_id;
|
||||
|
||||
vol = ubi_require_volume(argv[2]);
|
||||
if (!vol)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
vol_id = vol->vol_id;
|
||||
|
||||
ret = __ubi_remove_vol(vol);
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
printf("Removed UBI volume %s (id %d)\n", argv[2],
|
||||
vol_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_CMD_UBI_RENAME) && !strncmp(argv[1], "rename", 6))
|
||||
return ubi_rename_vol(argv[2], argv[3]);
|
||||
if (IS_ENABLED(CONFIG_CMD_UBI_RENAME) && !strncmp(argv[1], "rename", 6)) {
|
||||
if (argc < 4) {
|
||||
printf("Please see usage\n");
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
ret = ubi_rename_vol(argv[2], argv[3]);
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
printf("UBI volume %s renamed to %s\n", argv[2], argv[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "skipcheck", 9) == 0) {
|
||||
/* E.g., change skip_check flag */
|
||||
if (argc == 4) {
|
||||
skipcheck = strncmp(argv[3], "on", 2) == 0;
|
||||
return ubi_set_skip_check(argv[2], skipcheck);
|
||||
ret = ubi_set_skip_check(argv[2], skipcheck);
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
printf("%s skip_check on volume %s\n",
|
||||
skipcheck ? "Set" : "Cleared", argv[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "write", 5) == 0) {
|
||||
int ret;
|
||||
|
||||
if (argc < 5) {
|
||||
printf("Please see usage\n");
|
||||
return 1;
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
addr = hextoul(argv[2], NULL);
|
||||
@@ -855,7 +912,7 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
argv[3]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret ? CMD_RET_FAILURE : 0;
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "read", 4) == 0) {
|
||||
@@ -874,12 +931,29 @@ static int do_ubi(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
|
||||
}
|
||||
|
||||
if (argc == 3) {
|
||||
return ubi_volume_read(argv[3], (char *)addr, 0, size);
|
||||
vol = ubi_require_volume(argv[3]);
|
||||
if (!vol)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
if (!size) {
|
||||
printf("No size specified -> Using max size (%lld)\n",
|
||||
vol->used_bytes);
|
||||
size = vol->used_bytes;
|
||||
}
|
||||
|
||||
ret = __ubi_volume_read(vol, (void *)addr, 0, size);
|
||||
if (ret)
|
||||
return CMD_RET_FAILURE;
|
||||
|
||||
printf("%lld bytes read from volume %s to 0x%lx\n",
|
||||
size, argv[3], addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Please see usage\n");
|
||||
return 1;
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@
|
||||
static int ubifs_initialized;
|
||||
static int ubifs_mounted;
|
||||
|
||||
int cmd_ubifs_mount(char *vol_name)
|
||||
int cmd_ubifs_mount(const char *vol_name)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
Vendored
+20
@@ -739,6 +739,26 @@ config ENV_UBI_VOLUME_REDUND
|
||||
help
|
||||
Name of the redundant volume that you want to store the environment in.
|
||||
|
||||
config ENV_UBI_VOLUME_CREATE
|
||||
bool "Create UBI volume if it does not exist"
|
||||
depends on ENV_IS_IN_UBI
|
||||
help
|
||||
This option is useful if U-Boot will be booted from a fresh device
|
||||
where the environment volume has not been created.
|
||||
This is a common case where factory UBI image contains only volumes
|
||||
with valid data.
|
||||
By enabling this option, any missing environment volumes will be
|
||||
created before loading.
|
||||
If ENV_UBI_VOLUME_REDUND is also enabled, both volumes will be
|
||||
created.
|
||||
|
||||
config ENV_UBI_VOLUME_STATIC
|
||||
bool "Create static UBI volume"
|
||||
depends on ENV_UBI_VOLUME_CREATE
|
||||
help
|
||||
By default environment volume will be dynamic.
|
||||
Enable this option to create static volume.
|
||||
|
||||
config ENV_UBI_VID_OFFSET
|
||||
int "ubi environment VID offset"
|
||||
depends on ENV_IS_IN_UBI
|
||||
|
||||
@@ -103,12 +103,30 @@ static int env_ubi_save(void)
|
||||
}
|
||||
#endif /* CONFIG_ENV_REDUNDANT */
|
||||
|
||||
static int env_ubi_volume_create(const char *volume)
|
||||
{
|
||||
bool dynamic = !IS_ENABLED(CONFIG_ENV_UBI_VOLUME_STATIC);
|
||||
struct ubi_volume *vol;
|
||||
int ret;
|
||||
|
||||
vol = ubi_find_volume(volume);
|
||||
if (vol)
|
||||
return 0;
|
||||
|
||||
ret = ubi_create_vol(volume, CONFIG_ENV_SIZE, dynamic, UBI_VOL_NUM_AUTO,
|
||||
false);
|
||||
if (ret)
|
||||
printf("Failed to create environment volume '%s'\n", volume);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ENV_REDUNDANT
|
||||
static int env_ubi_load(void)
|
||||
{
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, env1_buf, CONFIG_ENV_SIZE);
|
||||
ALLOC_CACHE_ALIGN_BUFFER(char, env2_buf, CONFIG_ENV_SIZE);
|
||||
int read1_fail, read2_fail;
|
||||
int read1_fail, read2_fail, create1_fail = 0, create2_fail = 0;
|
||||
env_t *tmp_env1, *tmp_env2;
|
||||
|
||||
/*
|
||||
@@ -132,17 +150,35 @@ static int env_ubi_load(void)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, (void *)tmp_env1, 0,
|
||||
CONFIG_ENV_SIZE);
|
||||
if (read1_fail)
|
||||
printf("\n** Unable to read env from %s:%s **\n",
|
||||
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
|
||||
if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) {
|
||||
create1_fail = env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME);
|
||||
create2_fail = env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME_REDUND);
|
||||
if (create1_fail && create2_fail) {
|
||||
env_set_default(NULL, 0);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
|
||||
(void *)tmp_env2, 0, CONFIG_ENV_SIZE);
|
||||
if (read2_fail)
|
||||
printf("\n** Unable to read redundant env from %s:%s **\n",
|
||||
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME_REDUND);
|
||||
if (!create1_fail) {
|
||||
read1_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME, tmp_env1, 0,
|
||||
CONFIG_ENV_SIZE);
|
||||
if (read1_fail)
|
||||
printf("\n** Unable to read env from %s:%s **\n",
|
||||
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
|
||||
} else {
|
||||
read1_fail = create1_fail;
|
||||
}
|
||||
|
||||
if (!create2_fail) {
|
||||
read2_fail = ubi_volume_read(CONFIG_ENV_UBI_VOLUME_REDUND,
|
||||
tmp_env2, 0, CONFIG_ENV_SIZE);
|
||||
if (read2_fail)
|
||||
printf("\n** Unable to read redundant env from %s:%s **\n",
|
||||
CONFIG_ENV_UBI_PART,
|
||||
CONFIG_ENV_UBI_VOLUME_REDUND);
|
||||
} else {
|
||||
read2_fail = create2_fail;
|
||||
}
|
||||
|
||||
return env_import_redund((char *)tmp_env1, read1_fail, (char *)tmp_env2,
|
||||
read2_fail, H_EXTERNAL);
|
||||
@@ -169,6 +205,13 @@ static int env_ubi_load(void)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_ENV_UBI_VOLUME_CREATE)) {
|
||||
if (env_ubi_volume_create(CONFIG_ENV_UBI_VOLUME)) {
|
||||
env_set_default(NULL, 0);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
if (ubi_volume_read(CONFIG_ENV_UBI_VOLUME, buf, 0, CONFIG_ENV_SIZE)) {
|
||||
printf("\n** Unable to read env from %s:%s **\n",
|
||||
CONFIG_ENV_UBI_PART, CONFIG_ENV_UBI_VOLUME);
|
||||
|
||||
+1
-1
@@ -2694,7 +2694,7 @@ MODULE_VERSION(__stringify(UBIFS_VERSION));
|
||||
MODULE_AUTHOR("Artem Bityutskiy, Adrian Hunter");
|
||||
MODULE_DESCRIPTION("UBIFS - UBI File System");
|
||||
#else
|
||||
int uboot_ubifs_mount(char *vol_name)
|
||||
int uboot_ubifs_mount(const char *vol_name)
|
||||
{
|
||||
struct dentry *ret;
|
||||
int flags;
|
||||
|
||||
+2
-2
@@ -544,7 +544,7 @@ static unsigned long ubifs_findfile(struct super_block *sb, char *filename)
|
||||
*(next++) = '\0';
|
||||
}
|
||||
ret = ubifs_finddir(sb, name, root_inum, &inum);
|
||||
if (!ret) {
|
||||
if (ret <= 0) {
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
@@ -991,7 +991,7 @@ void ubifs_close(void)
|
||||
}
|
||||
|
||||
/* Compat wrappers for common/cmd_ubifs.c */
|
||||
int ubifs_load(char *filename, unsigned long addr, u32 size)
|
||||
int ubifs_load(const char *filename, unsigned long addr, u32 size)
|
||||
{
|
||||
loff_t actread;
|
||||
int err;
|
||||
|
||||
+99
-7
@@ -44,15 +44,107 @@
|
||||
#endif
|
||||
|
||||
/* functions */
|
||||
extern int ubi_mtd_param_parse(const char *val, struct kernel_param *kp);
|
||||
extern int ubi_init(void);
|
||||
extern void ubi_exit(void);
|
||||
extern int ubi_part(char *part_name, const char *vid_header_offset);
|
||||
extern int ubi_volume_write(char *volume, void *buf, loff_t offset, size_t size);
|
||||
extern int ubi_volume_read(char *volume, char *buf, loff_t offset, size_t size);
|
||||
int ubi_mtd_param_parse(const char *val, struct kernel_param *kp);
|
||||
int ubi_init(void);
|
||||
void ubi_exit(void);
|
||||
|
||||
/**
|
||||
* ubi_detach() - detach UBI from MTD partition
|
||||
*
|
||||
* This function performs the cleanup of the UBI subsystem to make sure the
|
||||
* MTD partition can be safely used for another purpose, or be attached again
|
||||
* with ubi_part().
|
||||
*
|
||||
* Any mounted UBIFS will be unmounted automatically.
|
||||
*
|
||||
* Return: 0
|
||||
*/
|
||||
int ubi_detach(void);
|
||||
|
||||
/**
|
||||
* ubi_part() - attach UBI to MTD partition
|
||||
* @part_name: name of the MTD partition to attach
|
||||
* @vid_header_offset: VID header offset (string)
|
||||
*
|
||||
* This function detaches any existing UBI device, then probes for the
|
||||
* specified MTD partition, and then scans it to initialize UBI.
|
||||
*
|
||||
* @vid_header_offset is optional and is usually set to NULL.
|
||||
*
|
||||
* Return: 0 on success, or -ve on error.
|
||||
*/
|
||||
int ubi_part(const char *part_name, const char *vid_header_offset);
|
||||
|
||||
/**
|
||||
* ubi_volume_write() - write data to UBI volume
|
||||
* @volume: name of the volume to write to
|
||||
* @buf: data buffer to be written
|
||||
* @offset: start offset for writing
|
||||
* @size: number of bytes to write
|
||||
*
|
||||
* This function writes data to the specific UBI volume. If the offset is zero,
|
||||
* it initiates a full volume update. Otherwise, it performs an offset-based
|
||||
* write using LEB changes.
|
||||
*
|
||||
* Return: 0 on success, or -ve on error.
|
||||
*/
|
||||
int ubi_volume_write(const char *volume, const void *buf, loff_t offset,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* ubi_volume_read() - read data from UBI volume
|
||||
* @volume: name of the volume to read from
|
||||
* @buf: buffer to hold the read data
|
||||
* @offset: start offset for reading
|
||||
* @size: number of bytes to read
|
||||
*
|
||||
* This function reads data from the specified UBI volume. If @size is zero,
|
||||
* the function reads the entire volume content starting from @offset.
|
||||
*
|
||||
* Return: 0 on success, or -ve on error.
|
||||
*/
|
||||
int ubi_volume_read(const char *volume, void *buf, loff_t offset, size_t size);
|
||||
|
||||
/**
|
||||
* ubi_create_vol() - create UBI volume
|
||||
* @volume: name of the volume to create
|
||||
* @size: size of the volume in bytes
|
||||
* @dynamic: create dynamic volume if set to true
|
||||
* @vol_id: volume ID
|
||||
* @skipcheck: skip CRC check on this volume if set to true
|
||||
*
|
||||
* This function creates a new UBI volume with the specified parameters.
|
||||
* If @size is negative, all available space will be used.
|
||||
* For volume ID auto assignment, pass %UBI_VOL_NUM_AUTO to @vol_id.
|
||||
*
|
||||
* Return: 0 on success, or -ve on error.
|
||||
*/
|
||||
int ubi_create_vol(const char *volume, int64_t size, bool dynamic, int vol_id,
|
||||
bool skipcheck);
|
||||
|
||||
/**
|
||||
* ubi_find_volume() - find UBI volume by name
|
||||
* @volume: name of the volume to find
|
||||
*
|
||||
* This function searches for a UBI volume with the specified name in the
|
||||
* current UBI device.
|
||||
*
|
||||
* Return: pointer to the UBI volume structure, or %NULL if not found.
|
||||
*/
|
||||
struct ubi_volume *ubi_find_volume(const char *volume);
|
||||
|
||||
/**
|
||||
* ubi_remove_vol() - remove UBI volume
|
||||
* @volume: name of the volume to remove
|
||||
*
|
||||
* This function removes an existing UBI volume from the current UBI device.
|
||||
*
|
||||
* Return: 0 on success, or -ve on error.
|
||||
*/
|
||||
int ubi_remove_vol(const char *volume);
|
||||
|
||||
extern struct ubi_device *ubi_devices[];
|
||||
int cmd_ubifs_mount(char *vol_name);
|
||||
int cmd_ubifs_mount(const char *vol_name);
|
||||
int cmd_ubifs_umount(void);
|
||||
|
||||
#if IS_ENABLED(CONFIG_UBI_BLOCK)
|
||||
|
||||
@@ -18,10 +18,10 @@ struct blk_desc;
|
||||
struct disk_partition;
|
||||
|
||||
int ubifs_init(void);
|
||||
int uboot_ubifs_mount(char *vol_name);
|
||||
int uboot_ubifs_mount(const char *vol_name);
|
||||
void uboot_ubifs_umount(void);
|
||||
int ubifs_is_mounted(void);
|
||||
int ubifs_load(char *filename, unsigned long addr, u32 size);
|
||||
int ubifs_load(const char *filename, unsigned long addr, u32 size);
|
||||
|
||||
int ubifs_set_blk_dev(struct blk_desc *rbdd, struct disk_partition *info);
|
||||
int ubifs_ls(const char *dir_name);
|
||||
|
||||
Reference in New Issue
Block a user