From 324d1ed403564b29691677fc19dfdb1474bd6a6f Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Sun, 4 Jan 2026 16:18:59 +0100 Subject: [PATCH] genio: u-boot: patch: UFS 4k UMS fixes + BTRFS fixes/enablement - backport fixes from upstream u-boot for - BTRFS (plus enable BTRFS and BZIP2 support for radxa-nio-12l) - tested with `CARD_DEVICE=/dev/mmcblk1 ROOTFS_TYPE=btrfs BTRFS_COMPRESSION=zstd` (no UFS!) - also with `EXT=ufs CARD_DEVICE=/dev/sdc ROOTFS_TYPE=btrfs BTRFS_COMPRESSION=zstd` (UFS!) - 4k block size UFS for UMS: fixes block size issue (USB issues unhandled) - Enable "bind" command for the Mediatek-standard USB Gadget Ethernet --- ...IO-radxa-nio-12l-Enable-bind-command.patch | 56 ++ ...tiple-sector-sizes-plus-three-others.patch | 545 ++++++++++++++++++ ...04-UPSTREAM-multiple-fixes-for-btrfs.patch | 518 +++++++++++++++++ ...o-12l-Enable-BTRFS-and-BZIP2-support.patch | 78 +++ 4 files changed, 1197 insertions(+) create mode 100644 patch/u-boot/u-boot-genio/3302-GENIO-radxa-nio-12l-Enable-bind-command.patch create mode 100644 patch/u-boot/u-boot-genio/3303-UPSTREAM-usb-gadget-UMS-support-multiple-sector-sizes-plus-three-others.patch create mode 100644 patch/u-boot/u-boot-genio/3304-UPSTREAM-multiple-fixes-for-btrfs.patch create mode 100644 patch/u-boot/u-boot-genio/3305-GENIO-radxa-nio-12l-Enable-BTRFS-and-BZIP2-support.patch diff --git a/patch/u-boot/u-boot-genio/3302-GENIO-radxa-nio-12l-Enable-bind-command.patch b/patch/u-boot/u-boot-genio/3302-GENIO-radxa-nio-12l-Enable-bind-command.patch new file mode 100644 index 0000000000..c3081a7268 --- /dev/null +++ b/patch/u-boot/u-boot-genio/3302-GENIO-radxa-nio-12l-Enable-bind-command.patch @@ -0,0 +1,56 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Sat, 3 Jan 2026 21:06:01 +0100 +Subject: GENIO: radxa-nio-12l: Enable bind command + +After commit 9bc199d7ea5 ("GENIO: board: 350/510/700/1200 EVK: Drop +deprecated usb_ether_init()") USB Ethernet Gadget needs to be manually +binded using the `bind` command. Let's enable that on Radxa NIO-12L. + +Fixes: 8d921703e1fc5b446b041a7c81e93ca0455d573c # when nio-12l did not exist yet +Signed-off-by: Ricardo Pardini +--- + configs/genio_1200_radxa_nio_12l_d16_defconfig | 1 + + configs/genio_1200_radxa_nio_12l_d4_defconfig | 1 + + configs/genio_1200_radxa_nio_12l_d8_defconfig | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/configs/genio_1200_radxa_nio_12l_d16_defconfig b/configs/genio_1200_radxa_nio_12l_d16_defconfig +index 111111111111..222222222222 100644 +--- a/configs/genio_1200_radxa_nio_12l_d16_defconfig ++++ b/configs/genio_1200_radxa_nio_12l_d16_defconfig +@@ -36,6 +36,7 @@ CONFIG_CMD_NVEDIT_EFI=y + CONFIG_CMD_NVEDIT_INFO=y + # CONFIG_CMD_CRC32 is not set + CONFIG_CMD_ADC=y ++CONFIG_CMD_BIND=y + CONFIG_CMD_CLK=y + CONFIG_CMD_DFU=y + CONFIG_CMD_DM=y +diff --git a/configs/genio_1200_radxa_nio_12l_d4_defconfig b/configs/genio_1200_radxa_nio_12l_d4_defconfig +index 111111111111..222222222222 100644 +--- a/configs/genio_1200_radxa_nio_12l_d4_defconfig ++++ b/configs/genio_1200_radxa_nio_12l_d4_defconfig +@@ -36,6 +36,7 @@ CONFIG_CMD_NVEDIT_EFI=y + CONFIG_CMD_NVEDIT_INFO=y + # CONFIG_CMD_CRC32 is not set + CONFIG_CMD_ADC=y ++CONFIG_CMD_BIND=y + CONFIG_CMD_CLK=y + CONFIG_CMD_DFU=y + CONFIG_CMD_DM=y +diff --git a/configs/genio_1200_radxa_nio_12l_d8_defconfig b/configs/genio_1200_radxa_nio_12l_d8_defconfig +index 111111111111..222222222222 100644 +--- a/configs/genio_1200_radxa_nio_12l_d8_defconfig ++++ b/configs/genio_1200_radxa_nio_12l_d8_defconfig +@@ -36,6 +36,7 @@ CONFIG_CMD_NVEDIT_EFI=y + CONFIG_CMD_NVEDIT_INFO=y + # CONFIG_CMD_CRC32 is not set + CONFIG_CMD_ADC=y ++CONFIG_CMD_BIND=y + CONFIG_CMD_CLK=y + CONFIG_CMD_DFU=y + CONFIG_CMD_DM=y +-- +Armbian + diff --git a/patch/u-boot/u-boot-genio/3303-UPSTREAM-usb-gadget-UMS-support-multiple-sector-sizes-plus-three-others.patch b/patch/u-boot/u-boot-genio/3303-UPSTREAM-usb-gadget-UMS-support-multiple-sector-sizes-plus-three-others.patch new file mode 100644 index 0000000000..133d89aad2 --- /dev/null +++ b/patch/u-boot/u-boot-genio/3303-UPSTREAM-usb-gadget-UMS-support-multiple-sector-sizes-plus-three-others.patch @@ -0,0 +1,545 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tom Rini +Date: Wed, 5 Apr 2023 19:48:57 -0400 +Subject: UPSTREAM: usb: gadget: UMS: support multiple sector sizes (plus three + others) + +--> rpardini: this indeed fixes UFS support for UMS. Unfortunately, + it seems there's still trouble with USB/OTG impl + itself on Mediatek; UMS doesn't really work either + with MMC or with UFS. Still, this would be needed + when the USB stuff is hopefully fixed. + +--> rpardini: This cherry-picks and squashes upstream revisions: +---> 73b39a76e34a3b88a7a2c58588c9a5a604a51d90 + +usb: gadget: f_mass_storage: Rework do_request_sense slightly + +When building with clang, it notes that sdinfo may be unused +uninitialized in some cases. This appears to be true from reading the +code, and we can simply set the variable to zero to start with and be as +correct as before. + +Signed-off-by: Tom Rini +Reviewed-by: Marek Vasut + +---> f032260c7c336cf88c1914286fd42a1588080db3 + +cmd: ums: Use plain udevice for UDC controller interaction + +Convert to plain udevice interaction with UDC controller +device, avoid the use of UDC uclass dev_array . + +Reviewed-by: Mattijs Korpershoek +Tested-by: Mattijs Korpershoek # on khadas vim3 +Signed-off-by: Marek Vasut + +---> 1041ee64eb18f7a3af30085765ced149cb4dc7cf + +usb: gadget: f_mass_storage: Stop ums on START-STOP UNIT SCSI command + +Exit the UMS handler loop in case START-STOP UNIT SCSI command is +received. This is sent e.g. by the util-linux eject(1) command and +indicates to the device that it is supposed to spin down the media +and enter low power state. + +This effectively adds support for exitting the 'ums' command from +host using 'eject /dev/sdN' that is on par with 'dfu-util -e' . + +Signed-off-by: Marek Vasut +Reviewed-by: Mattijs Korpershoek +Link: https://lore.kernel.org/r/20231107001018.55640-1-marex@denx.de +Signed-off-by: Mattijs Korpershoek + +---> 304fa0aa445384e5e681a54abf413850591cec10 + +usb: gadget: UMS: support multiple sector sizes + +UFS storage often uses a 4096-byte sector size, add support for dynamic +sector sizes based loosely on the Linux implementation. + +Support for dynamic sector sizes changes the types used in some +divisions, resulting in the compiler attempting to use +libgcc helpers (__aeabi_ldivmod). +Replace these divisions with calls to lldiv() to handle this correctly. + +Reviewed-by: Mattijs Korpershoek +Reviewed-by: Neil Armstrong +Signed-off-by: Caleb Connolly +Link: https://lore.kernel.org/r/20240320-b4-qcom-usb-v4-4-41be480172e1@linaro.org +[mkorpershoek: squashed the lldiv() fix from caleb] +Signed-off-by: Mattijs Korpershoek +--- + cmd/usb_mass_storage.c | 14 +- + drivers/usb/gadget/f_mass_storage.c | 120 ++++++---- + drivers/usb/gadget/storage_common.c | 12 +- + include/usb_mass_storage.h | 3 +- + 4 files changed, 85 insertions(+), 64 deletions(-) + +diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c +index 111111111111..222222222222 100644 +--- a/cmd/usb_mass_storage.c ++++ b/cmd/usb_mass_storage.c +@@ -87,10 +87,6 @@ static int ums_init(const char *devtype, const char *devnums_part_str) + if (!strchr(devnum_part_str, ':')) + partnum = 0; + +- /* f_mass_storage.c assumes SECTOR_SIZE sectors */ +- if (block_dev->blksz != SECTOR_SIZE) +- goto cleanup; +- + ums_new = realloc(ums, (ums_count + 1) * sizeof(*ums)); + if (!ums_new) + goto cleanup; +@@ -143,6 +139,7 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, + const char *devtype; + const char *devnum; + unsigned int controller_index; ++ struct udevice *udc; + int rc; + int cable_ready_timeout __maybe_unused; + +@@ -164,13 +161,14 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, + + controller_index = (unsigned int)(simple_strtoul( + usb_controller, NULL, 0)); +- if (usb_gadget_initialize(controller_index)) { ++ rc = udc_device_get_by_index(controller_index, &udc); ++ if (rc) { + pr_err("Couldn't init USB controller.\n"); + rc = CMD_RET_FAILURE; + goto cleanup_ums_init; + } + +- rc = fsg_init(ums, ums_count, controller_index); ++ rc = fsg_init(ums, ums_count, udc); + if (rc) { + pr_err("fsg_init failed\n"); + rc = CMD_RET_FAILURE; +@@ -215,7 +213,7 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, + } + + while (1) { +- usb_gadget_handle_interrupts(controller_index); ++ dm_usb_gadget_handle_interrupts(udc); + + rc = fsg_main_thread(NULL); + if (rc) { +@@ -237,7 +235,7 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, + cleanup_register: + g_dnl_unregister(); + cleanup_board: +- usb_gadget_release(controller_index); ++ udc_device_put(udc); + cleanup_ums_init: + ums_fini(); + +diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c +index 111111111111..222222222222 100644 +--- a/drivers/usb/gadget/f_mass_storage.c ++++ b/drivers/usb/gadget/f_mass_storage.c +@@ -240,6 +240,7 @@ + /* #define DUMP_MSGS */ + + #include ++#include + #include + #include + #include +@@ -327,6 +328,7 @@ struct fsg_common { + unsigned int short_packet_received:1; + unsigned int bad_lun_okay:1; + unsigned int running:1; ++ unsigned int eject:1; + + int thread_wakeup_needed; + struct completion thread_notifier; +@@ -435,7 +437,7 @@ static void set_bulk_out_req_length(struct fsg_common *common, + static struct ums *ums; + static int ums_count; + static struct fsg_common *the_fsg_common; +-static unsigned int controller_index; ++static struct udevice *udcdev; + + static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) + { +@@ -669,6 +671,10 @@ static int sleep_thread(struct fsg_common *common) + } + + if (k == 10) { ++ /* Handle START-STOP UNIT */ ++ if (common->eject) ++ return -EPIPE; ++ + /* Handle CTRL+C */ + if (ctrlc()) + return -EPIPE; +@@ -680,7 +686,7 @@ static int sleep_thread(struct fsg_common *common) + k = 0; + } + +- usb_gadget_handle_interrupts(controller_index); ++ dm_usb_gadget_handle_interrupts(udcdev); + } + common->thread_wakeup_needed = 0; + return rc; +@@ -719,12 +725,13 @@ static int do_read(struct fsg_common *common) + curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; + return -EINVAL; + } +- file_offset = ((loff_t) lba) << 9; ++ file_offset = ((loff_t)lba) << curlun->blkbits; + + /* Carry out the file reads */ + amount_left = common->data_size_from_cmnd; +- if (unlikely(amount_left == 0)) ++ if (unlikely(amount_left == 0)) { + return -EIO; /* No default reply */ ++ } + + for (;;) { + +@@ -763,13 +770,13 @@ static int do_read(struct fsg_common *common) + + /* Perform the read */ + rc = ums[common->lun].read_sector(&ums[common->lun], +- file_offset / SECTOR_SIZE, +- amount / SECTOR_SIZE, ++ lldiv(file_offset, curlun->blksize), ++ lldiv(amount, curlun->blksize), + (char __user *)bh->buf); + if (!rc) + return -EIO; + +- nread = rc * SECTOR_SIZE; ++ nread = rc * curlun->blksize; + + VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, +@@ -782,7 +789,7 @@ static int do_read(struct fsg_common *common) + } else if (nread < amount) { + LDBG(curlun, "partial file read: %d/%u\n", + (int) nread, amount); +- nread -= (nread & 511); /* Round down to a block */ ++ nread -= (nread & (curlun->blksize - 1)); /* Round down to a block */ + } + file_offset += nread; + amount_left -= nread; +@@ -856,7 +863,7 @@ static int do_write(struct fsg_common *common) + + /* Carry out the file writes */ + get_some_more = 1; +- file_offset = usb_offset = ((loff_t) lba) << 9; ++ file_offset = usb_offset = ((loff_t)lba) << curlun->blkbits; + amount_left_to_req = common->data_size_from_cmnd; + amount_left_to_write = common->data_size_from_cmnd; + +@@ -888,7 +895,7 @@ static int do_write(struct fsg_common *common) + curlun->info_valid = 1; + continue; + } +- amount -= (amount & 511); ++ amount -= (amount & (curlun->blksize - 1)); + if (amount == 0) { + + /* Why were we were asked to transfer a +@@ -937,12 +944,12 @@ static int do_write(struct fsg_common *common) + + /* Perform the write */ + rc = ums[common->lun].write_sector(&ums[common->lun], +- file_offset / SECTOR_SIZE, +- amount / SECTOR_SIZE, ++ lldiv(file_offset, curlun->blksize), ++ lldiv(amount, curlun->blksize), + (char __user *)bh->buf); + if (!rc) + return -EIO; +- nwritten = rc * SECTOR_SIZE; ++ nwritten = rc * curlun->blksize; + + VLDBG(curlun, "file write %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, +@@ -955,7 +962,7 @@ static int do_write(struct fsg_common *common) + } else if (nwritten < amount) { + LDBG(curlun, "partial file write: %d/%u\n", + (int) nwritten, amount); +- nwritten -= (nwritten & 511); ++ nwritten -= (nwritten & (curlun->blksize - 1)); + /* Round down to a block */ + } + file_offset += nwritten; +@@ -1029,8 +1036,8 @@ static int do_verify(struct fsg_common *common) + return -EIO; /* No default reply */ + + /* Prepare to carry out the file verify */ +- amount_left = verification_length << 9; +- file_offset = ((loff_t) lba) << 9; ++ amount_left = verification_length << curlun->blkbits; ++ file_offset = ((loff_t) lba) << curlun->blkbits; + + /* Write out all the dirty buffers before invalidating them */ + +@@ -1053,12 +1060,12 @@ static int do_verify(struct fsg_common *common) + + /* Perform the read */ + rc = ums[common->lun].read_sector(&ums[common->lun], +- file_offset / SECTOR_SIZE, +- amount / SECTOR_SIZE, ++ lldiv(file_offset, curlun->blksize), ++ lldiv(amount, curlun->blksize), + (char __user *)bh->buf); + if (!rc) + return -EIO; +- nread = rc * SECTOR_SIZE; ++ nread = rc * curlun->blksize; + + VLDBG(curlun, "file read %u @ %llu -> %d\n", amount, + (unsigned long long) file_offset, +@@ -1070,7 +1077,7 @@ static int do_verify(struct fsg_common *common) + } else if (nread < amount) { + LDBG(curlun, "partial file verify: %d/%u\n", + (int) nread, amount); +- nread -= (nread & 511); /* Round down to a sector */ ++ nread -= (nread & (curlun->blksize - 1)); /* Round down to a sector */ + } + if (nread == 0) { + curlun->sense_data = SS_UNRECOVERED_READ_ERROR; +@@ -1117,7 +1124,7 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) + { + struct fsg_lun *curlun = &common->luns[common->lun]; + u8 *buf = (u8 *) bh->buf; +- u32 sd, sdinfo; ++ u32 sd, sdinfo = 0; + int valid; + + /* +@@ -1145,7 +1152,6 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) + if (!curlun) { /* Unsupported LUNs are okay */ + common->bad_lun_okay = 1; + sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; +- sdinfo = 0; + valid = 0; + } else { + sd = curlun->sense_data; +@@ -1179,7 +1185,7 @@ static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh) + + put_unaligned_be32(curlun->num_sectors - 1, &buf[0]); + /* Max logical block */ +- put_unaligned_be32(512, &buf[4]); /* Block length */ ++ put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ + return 8; + } + +@@ -1326,6 +1332,8 @@ static int do_start_stop(struct fsg_common *common) + return -EINVAL; + } + ++ common->eject = 1; ++ + return 0; + } + +@@ -1364,7 +1372,7 @@ static int do_read_format_capacities(struct fsg_common *common, + + put_unaligned_be32(curlun->num_sectors, &buf[0]); + /* Number of blocks */ +- put_unaligned_be32(512, &buf[4]); /* Block length */ ++ put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */ + buf[4] = 0x02; /* Current capacity */ + return 12; + } +@@ -1775,6 +1783,16 @@ static int check_command(struct fsg_common *common, int cmnd_size, + return 0; + } + ++/* wrapper of check_command for data size in blocks handling */ ++static int check_command_size_in_blocks(struct fsg_common *common, ++ int cmnd_size, enum data_direction data_dir, ++ unsigned int mask, int needs_medium, const char *name) ++{ ++ common->data_size_from_cmnd <<= common->luns[common->lun].blkbits; ++ return check_command(common, cmnd_size, data_dir, ++ mask, needs_medium, name); ++} ++ + + static int do_scsi_command(struct fsg_common *common) + { +@@ -1859,30 +1877,30 @@ static int do_scsi_command(struct fsg_common *common) + + case SC_READ_6: + i = common->cmnd[4]; +- common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; +- reply = check_command(common, 6, DATA_DIR_TO_HOST, +- (7<<1) | (1<<4), 1, +- "READ(6)"); ++ common->data_size_from_cmnd = (i == 0 ? 256 : i); ++ reply = check_command_size_in_blocks(common, 6, DATA_DIR_TO_HOST, ++ (7<<1) | (1<<4), 1, ++ "READ(6)"); + if (reply == 0) + reply = do_read(common); + break; + + case SC_READ_10: + common->data_size_from_cmnd = +- get_unaligned_be16(&common->cmnd[7]) << 9; +- reply = check_command(common, 10, DATA_DIR_TO_HOST, +- (1<<1) | (0xf<<2) | (3<<7), 1, +- "READ(10)"); ++ get_unaligned_be16(&common->cmnd[7]); ++ reply = check_command_size_in_blocks(common, 10, DATA_DIR_TO_HOST, ++ (1<<1) | (0xf<<2) | (3<<7), 1, ++ "READ(10)"); + if (reply == 0) + reply = do_read(common); + break; + + case SC_READ_12: + common->data_size_from_cmnd = +- get_unaligned_be32(&common->cmnd[6]) << 9; +- reply = check_command(common, 12, DATA_DIR_TO_HOST, +- (1<<1) | (0xf<<2) | (0xf<<6), 1, +- "READ(12)"); ++ get_unaligned_be32(&common->cmnd[6]); ++ reply = check_command_size_in_blocks(common, 12, DATA_DIR_TO_HOST, ++ (1<<1) | (0xf<<2) | (0xf<<6), 1, ++ "READ(12)"); + if (reply == 0) + reply = do_read(common); + break; +@@ -1977,30 +1995,30 @@ static int do_scsi_command(struct fsg_common *common) + + case SC_WRITE_6: + i = common->cmnd[4]; +- common->data_size_from_cmnd = (i == 0 ? 256 : i) << 9; +- reply = check_command(common, 6, DATA_DIR_FROM_HOST, +- (7<<1) | (1<<4), 1, +- "WRITE(6)"); ++ common->data_size_from_cmnd = (i == 0 ? 256 : i); ++ reply = check_command_size_in_blocks(common, 6, DATA_DIR_FROM_HOST, ++ (7<<1) | (1<<4), 1, ++ "WRITE(6)"); + if (reply == 0) + reply = do_write(common); + break; + + case SC_WRITE_10: + common->data_size_from_cmnd = +- get_unaligned_be16(&common->cmnd[7]) << 9; +- reply = check_command(common, 10, DATA_DIR_FROM_HOST, +- (1<<1) | (0xf<<2) | (3<<7), 1, +- "WRITE(10)"); ++ get_unaligned_be16(&common->cmnd[7]); ++ reply = check_command_size_in_blocks(common, 10, DATA_DIR_FROM_HOST, ++ (1<<1) | (0xf<<2) | (3<<7), 1, ++ "WRITE(10)"); + if (reply == 0) + reply = do_write(common); + break; + + case SC_WRITE_12: + common->data_size_from_cmnd = +- get_unaligned_be32(&common->cmnd[6]) << 9; +- reply = check_command(common, 12, DATA_DIR_FROM_HOST, +- (1<<1) | (0xf<<2) | (0xf<<6), 1, +- "WRITE(12)"); ++ get_unaligned_be32(&common->cmnd[6]); ++ reply = check_command_size_in_blocks(common, 12, DATA_DIR_FROM_HOST, ++ (1<<1) | (0xf<<2) | (0xf<<6), 1, ++ "WRITE(12)"); + if (reply == 0) + reply = do_write(common); + break; +@@ -2491,7 +2509,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, + for (i = 0; i < nluns; i++) { + common->luns[i].removable = 1; + +- rc = fsg_lun_open(&common->luns[i], ums[i].num_sectors, ""); ++ rc = fsg_lun_open(&common->luns[i], ums[i].num_sectors, ums->block_dev.blksz, ""); + if (rc) + goto error_luns; + } +@@ -2765,11 +2783,11 @@ int fsg_add(struct usb_configuration *c) + return fsg_bind_config(c->cdev, c, fsg_common); + } + +-int fsg_init(struct ums *ums_devs, int count, unsigned int controller_idx) ++int fsg_init(struct ums *ums_devs, int count, struct udevice *udc) + { + ums = ums_devs; + ums_count = count; +- controller_index = controller_idx; ++ udcdev = udc; + + return 0; + } +diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c +index 111111111111..222222222222 100644 +--- a/drivers/usb/gadget/storage_common.c ++++ b/drivers/usb/gadget/storage_common.c +@@ -269,6 +269,7 @@ struct device_attribute { int i; }; + #define ETOOSMALL 525 + + #include ++#include + #include + #include + +@@ -290,6 +291,8 @@ struct fsg_lun { + u32 sense_data; + u32 sense_data_info; + u32 unit_attention_data; ++ unsigned int blkbits; ++ unsigned int blksize; /* logical block size of bound block device */ + + struct device dev; + }; +@@ -566,7 +569,7 @@ static struct usb_gadget_strings fsg_stringtab = { + */ + + static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors, +- const char *filename) ++ unsigned int sector_size, const char *filename) + { + int ro; + +@@ -574,9 +577,12 @@ static int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors, + ro = curlun->initially_ro; + + curlun->ro = ro; +- curlun->file_length = num_sectors << 9; ++ curlun->file_length = num_sectors * sector_size; + curlun->num_sectors = num_sectors; +- debug("open backing file: %s\n", filename); ++ curlun->blksize = sector_size; ++ curlun->blkbits = order_base_2(sector_size >> 9) + 9; ++ debug("blksize: %u\n", sector_size); ++ debug("open backing file: '%s'\n", filename); + + return 0; + } +diff --git a/include/usb_mass_storage.h b/include/usb_mass_storage.h +index 111111111111..222222222222 100644 +--- a/include/usb_mass_storage.h ++++ b/include/usb_mass_storage.h +@@ -7,7 +7,6 @@ + #ifndef __USB_MASS_STORAGE_H__ + #define __USB_MASS_STORAGE_H__ + +-#define SECTOR_SIZE 0x200 + #include + #include + +@@ -25,7 +24,7 @@ struct ums { + struct blk_desc block_dev; + }; + +-int fsg_init(struct ums *ums_devs, int count, unsigned int controller_idx); ++int fsg_init(struct ums *ums_devs, int count, struct udevice *udc); + void fsg_cleanup(void); + int fsg_main_thread(void *); + int fsg_add(struct usb_configuration *c); +-- +Armbian + diff --git a/patch/u-boot/u-boot-genio/3304-UPSTREAM-multiple-fixes-for-btrfs.patch b/patch/u-boot/u-boot-genio/3304-UPSTREAM-multiple-fixes-for-btrfs.patch new file mode 100644 index 0000000000..c9f027d4d0 --- /dev/null +++ b/patch/u-boot/u-boot-genio/3304-UPSTREAM-multiple-fixes-for-btrfs.patch @@ -0,0 +1,518 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Qu Wenruo +Date: Fri, 30 Dec 2022 09:07:05 +0800 +Subject: UPSTREAM: multiple fixes for btrfs + +fs: btrfs: Do not free multi when guaranteed to be NULL + +multi is guaranteed to be NULL in the first two error exit paths so the +attempt to free it is not needed. Remove those calls. + +This issue found by Smatch. + +Signed-off-by: Andrew Goodbody +(cherry picked from commit 9204cae0937c0e26fcff1ee08e51ef37f59844fe) + +fs: btrfs: hide duplicate 'Cannot lookup file' error on 'load' + +Running commands such as 'load mmc 2:1 $addr $path' when path does not +exists will print an error twice if the file does not exist, e.g.: +``` +Cannot lookup file boot/boot.scr +Failed to load 'boot/boot.scr' +``` +(where the first line is printed by btrfs and the second by common fs +code) + +Historically other filesystems such as ext4 or fat have not been +printing a message here, so do the same here to avoid duplicate. + +The other error messages in this function are also somewhat redundant, +but bring useful diagnostics if they happen somewhere, so have been left +as printf. + +Note that if a user wants no message to be printed for optional file +loads, they have to check for file existence first with other commands +such as 'size'. + +Signed-off-by: Dominique Martinet +Reviewed-by: Qu Wenruo +(cherry picked from commit 6e988fde65b0a89d49c20553d47a8ec1e5461c12) + +fs: btrfs: fix out of bounds write + +Fix btrfs_read/read_and_truncate_page write out of bounds of destination +buffer. Old behavior break bootstd malloc'd buffers of exact file size. +Previously this OOB write have not been noticed because distroboot usually +read files into huge static memory areas. + +Signed-off-by: Alex Shumsky +Fixes: e342718 ("fs: btrfs: Implement btrfs_file_read()") +Reviewed-by: Qu Wenruo +(cherry picked from commit ee1941e4fec601a8444f49c7dad04ad700d501a6) + +fs: btrfs: fix reading when length specified + +The btrfs read function limits the read length to ensure that it +and the read offset do not together exceed the size of the file. +However, this size was only being queried if the read length was +passed a value of zero (meaning "whole file"), and the size is +defaulted to 0 otherwise. This means the clamp will just zero out +the length if one is specified, preventing reading of the file. + +Fix this by checking the file size unconditionally, and unifying +the default length and clamping logic as a single range check instead. + +This bug was discovered when trying to boot Linux with initrd= via +'bootefi' from a btrfs partition. The EFI stub entered an infinite +loop of zero-length reads while trying to read the initrd, and the +boot process stalled indefinitely. + +Signed-off-by: Sam Edwards +Reviewed-by: Qu Wenruo +(cherry picked from commit 6d6ea52b629c384fb8605678b9003d2a077f9148) + +btrfs: fix some error checking for btrfs_decompress() + +The btrfs_decompress() function mostly (u32)-1 on error but it can +also return -EPERM or other kernel error codes from zstd_decompress(). +The "ret" variable is an int, so we could just check for negatives. + +Signed-off-by: Dan Carpenter +Reviewed-by: Qu Wenruo +(cherry picked from commit 08404fa2087946bb370430d466fe5011f18ef072) + +fs: btrfs: Prevent error pointer dereference in list_subvolums() + +If btrfs_read_fs_root() fails with -ENOENT, then we go to the next +entry. Fine. But if it fails for a different reason then we need +to clean up and return an error code. In the current code it +doesn't clean up but instead dereferences "root" and crashes. + +Signed-off-by: Dan Carpenter +Reviewed-by: Marek Behun +Reviewed-by: Qu Wenruo +(cherry picked from commit c331efd08766aa610aa14c957856ef5b0fa915df) + +fs/btrfs: use asm/unaligned.h + +Use asm/unaligned.h instead of linux/unaligned/access_ok.h for unaligned +access. This is needed on architectures that doesn't handle unaligned +accesses directly. + +Signed-off-by: Jens Wiklander +Reviewed-by: Ilias Apalodimas +(cherry picked from commit 6ba08b3f56c93d2e97e5be3e9deccadd1e8c0796) + +btrfs: fix offset when reading compressed extents + +btrfs_read_extent_reg correctly computed the extent offset in the +BTRFS_COMPRESS_NONE case, but did not account for the 'offset - key.offset' +part correctly in the compressed case, making the function read +incorrect data. + +In the case I examined, the last 4k of a file was corrupted and +contained data from a few blocks prior, e.g. reading a 10k file with a +single extent: +btrfs_file_read() + -> btrfs_read_extent_reg + (aligned part loop, until 8k) + -> read_and_truncate_page + -> btrfs_read_extent_reg + (re-reads the last extent from 8k to the end, + incorrectly reading the first 2k of data) + +This can be reproduced as follow: +$ truncate -s 200M btr +$ mount btr -o compress /mnt +$ pat() { dd if=/dev/zero bs=1M count=$1 iflag=count_bytes status=none | tr '\0' "\\$2"; } +$ { pat 4K 1; pat 4K 2; pat 2K 3; } > /mnt/file +$ sync +$ filefrag -v /mnt/file +File size of /mnt/file is 10240 (3 blocks of 4096 bytes) + ext: logical_offset: physical_offset: length: expected: flags: + 0: 0.. 2: 3328.. 3330: 3: last,encoded,eof +$ umount /mnt + +Then in u-boot: +=> load scsi 0 2000000 file +10240 bytes read in 3 ms (3.3 MiB/s) +=> md 2001ff0 +02001ff0: 02020202 02020202 02020202 02020202 ................ +02002000: 01010101 01010101 01010101 01010101 ................ +02002010: 01010101 01010101 01010101 01010101 ................ + +(02002000 onwards should contain '03' pattern but went back to 01, +start of the extent) + +After patch, data is read properly: +=> md 2001ff0 +02001ff0: 02020202 02020202 02020202 02020202 ................ +02002000: 03030303 03030303 03030303 03030303 ................ +02002010: 03030303 03030303 03030303 03030303 ................ + +Note that the code previously (before commit e3427184f38a ("fs: btrfs: +Implement btrfs_file_read()")) did not split that read in two, so +this is a regression even if the previous code might not have been +handling offsets correctly either (something that booted now fails to +boot) + +Fixes: a26a6bedafcf ("fs: btrfs: Introduce btrfs_read_extent_inline() and btrfs_read_extent_reg()") +Signed-off-by: Dominique Martinet +Reviewed-by: Qu Wenruo +(cherry picked from commit b1d3013d024086c042dbae4ddd99db56bb55b5e7) + +fs: btrfs: limit the mapped length to the original length + +[BUG] +There is a bug report that btrfs driver caused hang during file read: + + This breaks btrfs on the HiFive Unmatched. + + => pci enum + PCIE-0: Link up (Gen1-x8, Bus0) + => nvme scan + => load nvme 0:2 0x8c000000 /boot/dtb/sifive/hifive-unmatched-a00.dtb + [hangs] + +[CAUSE] +The reporter provided some debug output: + + read_extent_data: cur=615817216, orig_len=16384, cur_len=16384 + read_extent_data: btrfs_map_block: cur_len=479944704; ret=0 + read_extent_data: ret=0 + read_extent_data: cur=615833600, orig_len=4096, cur_len=4096 + read_extent_data: btrfs_map_block: cur_len=479928320; ret=0 + +Note the second and the last line, the @cur_len is 450+MiB, which is +almost a chunk size. + +And inside __btrfs_map_block(), we limits the returned value to stripe +length, but that's depending on the chunk type: + + if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 | + BTRFS_BLOCK_GROUP_RAID1C3 | BTRFS_BLOCK_GROUP_RAID1C4 | + BTRFS_BLOCK_GROUP_RAID5 | BTRFS_BLOCK_GROUP_RAID6 | + BTRFS_BLOCK_GROUP_RAID10 | + BTRFS_BLOCK_GROUP_DUP)) { + /* we limit the length of each bio to what fits in a stripe */ + *length = min_t(u64, ce->size - offset, + map->stripe_len - stripe_offset); + } else { + *length = ce->size - offset; + } + +This means, if the chunk is SINGLE profile, then we don't limit the +returned length at all, and even for other profiles, we can still return +a length much larger than the requested one. + +[FIX] +Properly clamp the returned length, preventing it from returning a much +larger range than expected. + +Reported-by: Andreas Schwab +Signed-off-by: Qu Wenruo +(cherry picked from commit 511a1303c9cf9663c7d4312e3a0693319f41095b) + +fs/btrfs: handle data extents, which crosss stripe boundaries, correctly + +[BUG] +Since btrfs supports single device RAID0 at mkfs time after btrfs-progs +v5.14, if we create a single device raid0 btrfs, and created a file +crossing stripe boundary: + + # mkfs.btrfs -m dup -d raid0 test.img + # mount test.img mnt + # xfs_io -f -c "pwrite 0 128K" mnt/file + # umount mnt + +Since btrfs is using 64K as stripe length, above 128K data write is +definitely going to cross at least one stripe boundary. + +Then u-boot would fail to read above 128K file: + + => host bind 0 /home/adam/test.img + => ls host 0 + < > 131072 Fri Dec 30 00:18:25 2022 file + => load host 0 0 file + BTRFS: An error occurred while reading file file + Failed to load 'file' + +[CAUSE] +Unlike tree blocks read, data extent reads doesn't consider cases in which +one data extent can cross stripe boundary. + +In read_data_extent(), we just call btrfs_map_block() once and read the +first mapped range. + +And if the first mapped range is smaller than the desired range, it +would return error. + +But since even single device btrfs can utilize RAID0 profiles, the first +mapped range can only be at most 64K for RAID0 profiles, and cause false +error. + +[FIX] +Just like read_whole_eb(), we should call btrfs_map_block() in a loop +until we read all data. + +Since we're here, also add extra error messages for the following cases: + +- btrfs_map_block() failure + We already have the error message for it. + +- Missing device + This should not happen, as we only support single device for now. + +- __btrfs_devread() failure + +With this bug fixed, btrfs driver of u-boot can properly read the above +128K file, and have the correct content: + + => host bind 0 /home/adam/test.img + => ls host 0 + < > 131072 Fri Dec 30 00:18:25 2022 file + => load host 0 0 file + 131072 bytes read in 0 ms + => md5sum 0 0x20000 + md5 for 00000000 ... 0001ffff ==> d48858312a922db7eb86377f638dbc9f + ^^^ Above md5sum also matches. + +Reported-by: Sam Winchenbach +Signed-off-by: Qu Wenruo +(cherry picked from commit 11d567012558fab7da9d1189948cb6005c081ccd) +--- + fs/btrfs/btrfs.c | 17 ++-- + fs/btrfs/crypto/hash.c | 2 +- + fs/btrfs/disk-io.c | 49 +++++----- + fs/btrfs/inode.c | 16 ++- + fs/btrfs/subvolume.c | 1 + + fs/btrfs/volumes.c | 4 +- + 6 files changed, 49 insertions(+), 40 deletions(-) + +diff --git a/fs/btrfs/btrfs.c b/fs/btrfs/btrfs.c +index 111111111111..222222222222 100644 +--- a/fs/btrfs/btrfs.c ++++ b/fs/btrfs/btrfs.c +@@ -193,7 +193,7 @@ int btrfs_size(const char *file, loff_t *size) + ret = btrfs_lookup_path(fs_info->fs_root, BTRFS_FIRST_FREE_OBJECTID, + file, &root, &ino, &type, 40); + if (ret < 0) { +- printf("Cannot lookup file %s\n", file); ++ debug("Cannot lookup file %s\n", file); + return ret; + } + if (type != BTRFS_FT_REG_FILE) { +@@ -228,7 +228,7 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len, + { + struct btrfs_fs_info *fs_info = current_fs_info; + struct btrfs_root *root; +- loff_t real_size = 0; ++ loff_t real_size; + u64 ino; + u8 type; + int ret; +@@ -246,16 +246,13 @@ int btrfs_read(const char *file, void *buf, loff_t offset, loff_t len, + return -EINVAL; + } + +- if (!len) { +- ret = btrfs_size(file, &real_size); +- if (ret < 0) { +- error("Failed to get inode size: %s", file); +- return ret; +- } +- len = real_size; ++ ret = btrfs_size(file, &real_size); ++ if (ret < 0) { ++ error("Failed to get inode size: %s", file); ++ return ret; + } + +- if (len > real_size - offset) ++ if (!len || len > real_size - offset) + len = real_size - offset; + + ret = btrfs_file_read(root, ino, offset, len, buf); +diff --git a/fs/btrfs/crypto/hash.c b/fs/btrfs/crypto/hash.c +index 111111111111..222222222222 100644 +--- a/fs/btrfs/crypto/hash.c ++++ b/fs/btrfs/crypto/hash.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0+ + ++#include + #include +-#include + #include + #include + #include +diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c +index 111111111111..222222222222 100644 +--- a/fs/btrfs/disk-io.c ++++ b/fs/btrfs/disk-io.c +@@ -540,34 +540,39 @@ struct extent_buffer* read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr, + int read_extent_data(struct btrfs_fs_info *fs_info, char *data, u64 logical, + u64 *len, int mirror) + { +- u64 offset = 0; ++ u64 orig_len = *len; ++ u64 cur = logical; + struct btrfs_multi_bio *multi = NULL; + struct btrfs_device *device; + int ret = 0; +- u64 max_len = *len; + +- ret = btrfs_map_block(fs_info, READ, logical, len, &multi, mirror, +- NULL); +- if (ret) { +- fprintf(stderr, "Couldn't map the block %llu\n", +- logical + offset); +- goto err; +- } +- device = multi->stripes[0].dev; +- +- if (*len > max_len) +- *len = max_len; +- if (!device->desc || !device->part) { +- ret = -EIO; +- goto err; +- } ++ while (cur < logical + orig_len) { ++ u64 cur_len = logical + orig_len - cur; + +- ret = __btrfs_devread(device->desc, device->part, data, *len, +- multi->stripes[0].physical); +- if (ret != *len) +- ret = -EIO; +- else ++ ret = btrfs_map_block(fs_info, READ, cur, &cur_len, &multi, ++ mirror, NULL); ++ if (ret) { ++ error("Couldn't map the block %llu", cur); ++ goto err; ++ } ++ device = multi->stripes[0].dev; ++ if (!device->desc || !device->part) { ++ error("devid %llu is missing", device->devid); ++ ret = -EIO; ++ goto err; ++ } ++ ret = __btrfs_devread(device->desc, device->part, ++ data + (cur - logical), cur_len, ++ multi->stripes[0].physical); ++ if (ret != cur_len) { ++ error("read failed on devid %llu physical %llu", ++ device->devid, multi->stripes[0].physical); ++ ret = -EIO; ++ goto err; ++ } ++ cur += cur_len; + ret = 0; ++ } + err: + kfree(multi); + return ret; +diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c +index 111111111111..222222222222 100644 +--- a/fs/btrfs/inode.c ++++ b/fs/btrfs/inode.c +@@ -390,7 +390,7 @@ int btrfs_read_extent_inline(struct btrfs_path *path, + csize); + ret = btrfs_decompress(btrfs_file_extent_compression(leaf, fi), + cbuf, csize, dbuf, dsize); +- if (ret == (u32)-1) { ++ if (ret < 0) { + ret = -EIO; + goto out; + } +@@ -500,7 +500,7 @@ int btrfs_read_extent_reg(struct btrfs_path *path, + + ret = btrfs_decompress(btrfs_file_extent_compression(leaf, fi), cbuf, + csize, dbuf, dsize); +- if (ret == (u32)-1) { ++ if (ret < 0) { + ret = -EIO; + goto out; + } +@@ -511,7 +511,9 @@ int btrfs_read_extent_reg(struct btrfs_path *path, + if (ret < dsize) + memset(dbuf + ret, 0, dsize - ret); + /* Then copy the needed part */ +- memcpy(dest, dbuf + btrfs_file_extent_offset(leaf, fi), len); ++ memcpy(dest, ++ dbuf + btrfs_file_extent_offset(leaf, fi) + offset - key.offset, ++ len); + ret = len; + out: + free(cbuf); +@@ -638,7 +640,11 @@ static int read_and_truncate_page(struct btrfs_path *path, + extent_type = btrfs_file_extent_type(leaf, fi); + if (extent_type == BTRFS_FILE_EXTENT_INLINE) { + ret = btrfs_read_extent_inline(path, fi, buf); +- memcpy(dest, buf + page_off, min(page_len, ret)); ++ if (ret < 0) { ++ free(buf); ++ return ret; ++ } ++ memcpy(dest, buf + page_off, min3(page_len, ret, len)); + free(buf); + return len; + } +@@ -650,7 +656,7 @@ static int read_and_truncate_page(struct btrfs_path *path, + free(buf); + return ret; + } +- memcpy(dest, buf + page_off, page_len); ++ memcpy(dest, buf + page_off, min(page_len, len)); + free(buf); + return len; + } +diff --git a/fs/btrfs/subvolume.c b/fs/btrfs/subvolume.c +index 111111111111..222222222222 100644 +--- a/fs/btrfs/subvolume.c ++++ b/fs/btrfs/subvolume.c +@@ -199,6 +199,7 @@ static int list_subvolums(struct btrfs_fs_info *fs_info) + ret = PTR_ERR(root); + if (ret == -ENOENT) + goto next; ++ goto out; + } + ret = list_one_subvol(root, result); + if (ret < 0) +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 111111111111..222222222222 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -956,6 +956,7 @@ int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, + struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; + struct cache_extent *ce; + struct map_lookup *map; ++ u64 orig_len = *length; + u64 offset; + u64 stripe_offset; + u64 *raid_map = NULL; +@@ -972,12 +973,10 @@ int __btrfs_map_block(struct btrfs_fs_info *fs_info, int rw, + again: + ce = search_cache_extent(&map_tree->cache_tree, logical); + if (!ce) { +- kfree(multi); + *length = (u64)-1; + return -ENOENT; + } + if (ce->start > logical) { +- kfree(multi); + *length = ce->start - logical; + return -ENOENT; + } +@@ -1047,6 +1046,7 @@ again: + } else { + *length = ce->size - offset; + } ++ *length = min_t(u64, *length, orig_len); + + if (!multi_ret) + goto out; +-- +Armbian + diff --git a/patch/u-boot/u-boot-genio/3305-GENIO-radxa-nio-12l-Enable-BTRFS-and-BZIP2-support.patch b/patch/u-boot/u-boot-genio/3305-GENIO-radxa-nio-12l-Enable-BTRFS-and-BZIP2-support.patch new file mode 100644 index 0000000000..8e348bf239 --- /dev/null +++ b/patch/u-boot/u-boot-genio/3305-GENIO-radxa-nio-12l-Enable-BTRFS-and-BZIP2-support.patch @@ -0,0 +1,78 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Ricardo Pardini +Date: Sun, 4 Jan 2026 15:58:51 +0100 +Subject: GENIO: radxa-nio-12l: Enable BTRFS and BZIP2 support + +After cherry-picking from upstream, BTRFS should work, so enable it +for the NIO-12L. Also add support for general BZIP2 compression. + +Signed-off-by: Ricardo Pardini +--- + configs/genio_1200_radxa_nio_12l_d16_defconfig | 2 ++ + configs/genio_1200_radxa_nio_12l_d4_defconfig | 2 ++ + configs/genio_1200_radxa_nio_12l_d8_defconfig | 2 ++ + 3 files changed, 6 insertions(+) + +diff --git a/configs/genio_1200_radxa_nio_12l_d16_defconfig b/configs/genio_1200_radxa_nio_12l_d16_defconfig +index 111111111111..222222222222 100644 +--- a/configs/genio_1200_radxa_nio_12l_d16_defconfig ++++ b/configs/genio_1200_radxa_nio_12l_d16_defconfig +@@ -53,6 +53,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y + # CONFIG_CMD_ITEST is not set + # CONFIG_CMD_BLOCK_CACHE is not set + CONFIG_CMD_EFIDEBUG=y ++CONFIG_CMD_BTRFS=y + CONFIG_PARTITION_TYPE_GUID=y + CONFIG_ENV_IS_IN_SCSI=y + CONFIG_SYS_SCSI_ENV_DEV=1 +@@ -122,6 +123,7 @@ CONFIG_USB_ETHER=y + CONFIG_UFS=y + CONFIG_UFS_MEDIATEK=y + CONFIG_WDT=y ++CONFIG_BZIP2=y + CONFIG_OF_LIBFDT_OVERLAY=y + CONFIG_EFI_SET_TIME=y + CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +diff --git a/configs/genio_1200_radxa_nio_12l_d4_defconfig b/configs/genio_1200_radxa_nio_12l_d4_defconfig +index 111111111111..222222222222 100644 +--- a/configs/genio_1200_radxa_nio_12l_d4_defconfig ++++ b/configs/genio_1200_radxa_nio_12l_d4_defconfig +@@ -53,6 +53,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y + # CONFIG_CMD_ITEST is not set + # CONFIG_CMD_BLOCK_CACHE is not set + CONFIG_CMD_EFIDEBUG=y ++CONFIG_CMD_BTRFS=y + CONFIG_PARTITION_TYPE_GUID=y + CONFIG_ENV_IS_IN_SCSI=y + CONFIG_SYS_SCSI_ENV_DEV=1 +@@ -122,6 +123,7 @@ CONFIG_USB_ETHER=y + CONFIG_UFS=y + CONFIG_UFS_MEDIATEK=y + CONFIG_WDT=y ++CONFIG_BZIP2=y + CONFIG_OF_LIBFDT_OVERLAY=y + CONFIG_EFI_SET_TIME=y + CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +diff --git a/configs/genio_1200_radxa_nio_12l_d8_defconfig b/configs/genio_1200_radxa_nio_12l_d8_defconfig +index 111111111111..222222222222 100644 +--- a/configs/genio_1200_radxa_nio_12l_d8_defconfig ++++ b/configs/genio_1200_radxa_nio_12l_d8_defconfig +@@ -53,6 +53,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y + # CONFIG_CMD_ITEST is not set + # CONFIG_CMD_BLOCK_CACHE is not set + CONFIG_CMD_EFIDEBUG=y ++CONFIG_CMD_BTRFS=y + CONFIG_PARTITION_TYPE_GUID=y + CONFIG_ENV_IS_IN_SCSI=y + CONFIG_SYS_SCSI_ENV_DEV=1 +@@ -122,6 +123,7 @@ CONFIG_USB_ETHER=y + CONFIG_UFS=y + CONFIG_UFS_MEDIATEK=y + CONFIG_WDT=y ++CONFIG_BZIP2=y + CONFIG_OF_LIBFDT_OVERLAY=y + CONFIG_EFI_SET_TIME=y + CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y +-- +Armbian +