diff options
author | Tom Rini <trini@konsulko.com> | 2023-10-10 21:47:50 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-10-10 21:47:50 -0400 |
commit | be98a786b67dfcccde1f18ec7cbfe1584e03cebe (patch) | |
tree | 8a5006ab4a8b4c96494c0973706e0fe8eb738aed /drivers | |
parent | 833ff23047c50e4053fb1bda21f4e2c9f6a3aa6a (diff) | |
parent | 5fdd48066e8a055576294c3846be8ea3914e7902 (diff) |
Merge branch '2023-10-10-blk-sandbox-support-binding-a-device-with-a-given-logical-block-size'
To quote the author:
At present on Sandbox when binding to a host backing file, the host
block device is created with a hard-coded 512 bytes block size.
Such assumption works for most cases, but for situation that with a raw
image file dump from a pre-formatted GPT partitioned disk image from a
4KiB block size device, when binding this file to a host device and mapping
this device to a blkmap, "blkmap" command like "blkmap part" won't work
correctly, due to block size mismatch during parsing the partition table.
This series updates Sandbox block driver, as well as the blkmap driver,
to get rid of the hard-coded 512 bytes block size assumption.
This series is available at u-boot-x86/blk for testing.
Test log (512 block size):
=> host bind 0 test.img
=> host info
dev blocks blksz label path
0 262144 512 0 test.img
=> blkmap create 0
Created "0"
=> blkmap map 0 0 40000 linear host 0 0
Block 0x0+0x40000 mapped to block 0x0 of "host 0"
=> blkmap info
Device 0: Vendor: U-Boot Rev: 1.0 Prod: blkmap
Type: Hard Disk
Capacity: 128.0 MB = 0.1 GB (262144 x 512)
=> blkmap part
Partition Map for BLKMAP device 0 -- Partition Type: EFI
Part Start LBA End LBA Name
Attributes
Type GUID
Partition GUID
1 0x00000022 0x000000bd "u-boot-spl"
attrs: 0x0000000000000000
type: 5b193300-fc78-40cd-8002-e86c45580b47
(5b193300-fc78-40cd-8002-e86c45580b47)
guid: 0bb6bb6e-4aac-4c27-be03-016b01e7b941
2 0x00000822 0x00000c84 "u-boot"
attrs: 0x0000000000000000
type: 2e54b353-1271-4842-806f-e436d6af6985
(2e54b353-1271-4842-806f-e436d6af6985)
guid: 91d50814-8e31-4cc0-97dc-779e1dc59056
3 0x00000c85 0x0000cc84 "rootfs"
attrs: 0x0000000000000004
type: 0fc63daf-8483-4772-8e79-3d69d8477de4
(linux)
guid: 42799722-6e55-46e6-afa9-529e7af3f03b
Test log (4096 block size):
=> host bind 0 test.img 4096
=> host info
dev blocks blksz label path
0 32768 4096 0 test.img
=> blkmap create 0
Created "0"
=> blkmap map 0 0 8000 linear host 0 0
Block 0x0+0x8000 mapped to block 0x0 of "host 0"
=> blkmap info
Device 0: Vendor: U-Boot Rev: 1.0 Prod: blkmap
Type: Hard Disk
Capacity: 128.0 MB = 0.1 GB (32768 x 4096)
=> blkmap part
Partition Map for BLKMAP device 0 -- Partition Type: EFI
Part Start LBA End LBA Name
Attributes
Type GUID
Partition GUID
1 0x00000100 0x00001fff "primary"
attrs: 0x0000000000000000
type: 0fc63daf-8483-4772-8e79-3d69d8477de4
(linux)
guid: eba904d7-72c1-4dbd-bb4e-36be49cba5e3
2 0x00002000 0x00007ffa "primary"
attrs: 0x0000000000000000
type: 0fc63daf-8483-4772-8e79-3d69d8477de4
(linux)
guid: c48c360e-db47-46da-ab87-26416fad3cd3
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/dwc_ahsata.c | 3 | ||||
-rw-r--r-- | drivers/ata/fsl_sata.c | 3 | ||||
-rw-r--r-- | drivers/ata/sata_mv.c | 3 | ||||
-rw-r--r-- | drivers/ata/sata_sil.c | 3 | ||||
-rw-r--r-- | drivers/block/blk-uclass.c | 51 | ||||
-rw-r--r-- | drivers/block/blkmap.c | 16 | ||||
-rw-r--r-- | drivers/block/host-uclass.c | 15 | ||||
-rw-r--r-- | drivers/block/host_dev.c | 11 | ||||
-rw-r--r-- | drivers/mmc/mmc-uclass.c | 2 | ||||
-rw-r--r-- | drivers/nvme/nvme.c | 2 |
10 files changed, 44 insertions, 65 deletions
diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 6a4d861bf1e..b4d4e39c9b3 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -880,7 +880,8 @@ int dwc_ahsata_scan(struct udevice *dev) device_find_first_child(dev, &blk); if (!blk) { ret = blk_create_devicef(dev, "dwc_ahsata_blk", "blk", - UCLASS_AHCI, -1, 512, 0, &blk); + UCLASS_AHCI, -1, DEFAULT_BLKSZ, + 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c index 972101b29ce..969bc191f8e 100644 --- a/drivers/ata/fsl_sata.c +++ b/drivers/ata/fsl_sata.c @@ -888,7 +888,8 @@ static int fsl_ata_probe(struct udevice *dev) for (i = 0; i < nr_ports; i++) { snprintf(sata_name, sizeof(sata_name), "fsl_sata%d", i); ret = blk_create_devicef(dev, "sata_fsl_blk", sata_name, - UCLASS_AHCI, -1, 512, 0, &blk); + UCLASS_AHCI, -1, DEFAULT_BLKSZ, + 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 18c7a66db1b..1abea0b3093 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1076,7 +1076,8 @@ static int sata_mv_probe(struct udevice *dev) for (i = 0; i < nr_ports; i++) { ret = blk_create_devicef(dev, "sata_mv_blk", "blk", - UCLASS_AHCI, -1, 512, 0, &blk); + UCLASS_AHCI, -1, DEFAULT_BLKSZ, + 0, &blk); if (ret) { debug("Can't create device\n"); continue; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index b5e150d568b..43a91a79120 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -730,7 +730,8 @@ static int sil_pci_probe(struct udevice *dev) for (i = sata_info.portbase; i < sata_info.maxport; i++) { snprintf(sata_name, sizeof(sata_name), "sil_sata%d", i); ret = blk_create_devicef(dev, "sata_sil_blk", sata_name, - UCLASS_AHCI, -1, 512, 0, &blk); + UCLASS_AHCI, -1, DEFAULT_BLKSZ, + 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 885513893f6..f126547cc7e 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -178,17 +178,7 @@ struct blk_desc *blk_get_by_device(struct udevice *dev) return NULL; } -/** - * get_desc() - Get the block device descriptor for the given device number - * - * @uclass_id: Interface type - * @devnum: Device number (0 = first) - * @descp: Returns block device descriptor on success - * Return: 0 on success, -ENODEV if there is no such device and no device - * with a higher device number, -ENOENT if there is no such device but there - * is one with a higher number, or other -ve on other error. - */ -static int get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp) +int blk_get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp) { bool found_more = false; struct udevice *dev; @@ -240,7 +230,7 @@ int blk_list_part(enum uclass_id uclass_id) int ret; for (ok = 0, devnum = 0;; ++devnum) { - ret = get_desc(uclass_id, devnum, &desc); + ret = blk_get_desc(uclass_id, devnum, &desc); if (ret == -ENODEV) break; else if (ret) @@ -263,7 +253,7 @@ int blk_print_part_devnum(enum uclass_id uclass_id, int devnum) struct blk_desc *desc; int ret; - ret = get_desc(uclass_id, devnum, &desc); + ret = blk_get_desc(uclass_id, devnum, &desc); if (ret) return ret; if (desc->type == DEV_TYPE_UNKNOWN) @@ -280,7 +270,7 @@ void blk_list_devices(enum uclass_id uclass_id) int i; for (i = 0;; ++i) { - ret = get_desc(uclass_id, i, &desc); + ret = blk_get_desc(uclass_id, i, &desc); if (ret == -ENODEV) break; else if (ret) @@ -297,7 +287,7 @@ int blk_print_device_num(enum uclass_id uclass_id, int devnum) struct blk_desc *desc; int ret; - ret = get_desc(uclass_id, devnum, &desc); + ret = blk_get_desc(uclass_id, devnum, &desc); if (ret) return ret; printf("\nIDE device %d: ", devnum); @@ -312,7 +302,7 @@ int blk_show_device(enum uclass_id uclass_id, int devnum) int ret; printf("\nDevice %d: ", devnum); - ret = get_desc(uclass_id, devnum, &desc); + ret = blk_get_desc(uclass_id, devnum, &desc); if (ret == -ENODEV || ret == -ENOENT) { printf("unknown device\n"); return -ENODEV; @@ -327,35 +317,6 @@ int blk_show_device(enum uclass_id uclass_id, int devnum) return 0; } -ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, - lbaint_t blkcnt, void *buffer) -{ - struct blk_desc *desc; - ulong n; - int ret; - - ret = get_desc(uclass_id, devnum, &desc); - if (ret) - return ret; - n = blk_dread(desc, start, blkcnt, buffer); - if (IS_ERR_VALUE(n)) - return n; - - return n; -} - -ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, - lbaint_t blkcnt, const void *buffer) -{ - struct blk_desc *desc; - int ret; - - ret = get_desc(uclass_id, devnum, &desc); - if (ret) - return ret; - return blk_dwrite(desc, start, blkcnt, buffer); -} - int blk_select_hwpart(struct udevice *dev, int hwpart) { const struct blk_ops *ops = blk_get_ops(dev); diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c index 2bb0acc20f2..149a4cac3ea 100644 --- a/drivers/block/blkmap.c +++ b/drivers/block/blkmap.c @@ -171,11 +171,11 @@ int blkmap_map_linear(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, bd = dev_get_uclass_plat(bm->blk); lbd = dev_get_uclass_plat(lblk); - if (lbd->blksz != bd->blksz) - /* We could support block size translation, but we - * don't yet. - */ - return -EINVAL; + if (lbd->blksz != bd->blksz) { + /* update to match the mapped device */ + bd->blksz = lbd->blksz; + bd->log2blksz = LOG2(bd->blksz); + } linear = malloc(sizeof(*linear)); if (!linear) @@ -383,14 +383,14 @@ U_BOOT_DRIVER(blkmap_blk) = { .ops = &blkmap_blk_ops, }; -int blkmap_dev_bind(struct udevice *dev) +static int blkmap_dev_bind(struct udevice *dev) { struct blkmap *bm = dev_get_plat(dev); struct blk_desc *bd; int err; err = blk_create_devicef(dev, "blkmap_blk", "blk", UCLASS_BLKMAP, - dev_seq(dev), 512, 0, &bm->blk); + dev_seq(dev), DEFAULT_BLKSZ, 0, &bm->blk); if (err) return log_msg_ret("blk", err); @@ -410,7 +410,7 @@ int blkmap_dev_bind(struct udevice *dev) return 0; } -int blkmap_dev_unbind(struct udevice *dev) +static int blkmap_dev_unbind(struct udevice *dev) { struct blkmap *bm = dev_get_plat(dev); struct blkmap_slice *bms, *tmp; diff --git a/drivers/block/host-uclass.c b/drivers/block/host-uclass.c index 6460d968c23..b3647e3ce33 100644 --- a/drivers/block/host-uclass.c +++ b/drivers/block/host-uclass.c @@ -13,6 +13,7 @@ #include <blk.h> #include <dm.h> #include <malloc.h> +#include <part.h> #include <sandbox_host.h> #include <dm/device-internal.h> #include <dm/lists.h> @@ -29,7 +30,8 @@ struct host_priv { struct udevice *cur_dev; }; -int host_create_device(const char *label, bool removable, struct udevice **devp) +int host_create_device(const char *label, bool removable, unsigned long blksz, + struct udevice **devp) { char dev_name[30], *str, *label_new; struct host_sb_plat *plat; @@ -68,6 +70,12 @@ int host_create_device(const char *label, bool removable, struct udevice **devp) struct blk_desc *desc = dev_get_uclass_plat(blk); desc->removable = removable; + + /* update blk device's block size with the provided one */ + if (blksz != desc->blksz) { + desc->blksz = blksz; + desc->log2blksz = LOG2(desc->blksz); + } } plat = dev_get_plat(dev); @@ -95,12 +103,13 @@ int host_attach_file(struct udevice *dev, const char *filename) } int host_create_attach_file(const char *label, const char *filename, - bool removable, struct udevice **devp) + bool removable, unsigned long blksz, + struct udevice **devp) { struct udevice *dev; int ret; - ret = host_create_device(label, removable, &dev); + ret = host_create_device(label, removable, blksz, &dev); if (ret) return log_msg_ret("cre", ret); diff --git a/drivers/block/host_dev.c b/drivers/block/host_dev.c index 64422417b74..30c74157934 100644 --- a/drivers/block/host_dev.c +++ b/drivers/block/host_dev.c @@ -58,6 +58,11 @@ static int host_sb_attach_file(struct udevice *dev, const char *filename) size = os_filesize(fd); desc = dev_get_uclass_plat(blk); + if (size % desc->blksz) { + printf("The size of host backing file '%s' is not multiple of " + "the device block size\n", filename); + goto err_fname; + } desc->lba = size / desc->blksz; /* write this in last, when nothing can go wrong */ @@ -73,7 +78,7 @@ err_fname: return ret; } -int host_sb_detach_file(struct udevice *dev) +static int host_sb_detach_file(struct udevice *dev) { struct host_sb_plat *plat = dev_get_plat(dev); int ret; @@ -105,7 +110,7 @@ static int host_sb_bind(struct udevice *dev) int ret; ret = blk_create_devicef(dev, "sandbox_host_blk", "blk", UCLASS_HOST, - dev_seq(dev), 512, 0, &blk); + dev_seq(dev), DEFAULT_BLKSZ, 0, &blk); if (ret) return log_msg_ret("blk", ret); @@ -123,7 +128,7 @@ static int host_sb_bind(struct udevice *dev) return 0; } -struct host_ops host_sb_ops = { +static struct host_ops host_sb_ops = { .attach_file = host_sb_attach_file, .detach_file = host_sb_detach_file, }; diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 0e157672eae..328456831dd 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -412,7 +412,7 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) debug("%s: alias devnum=%d\n", __func__, dev_seq(dev)); ret = blk_create_devicef(dev, "mmc_blk", "blk", UCLASS_MMC, - dev_seq(dev), 512, 0, &bdev); + dev_seq(dev), DEFAULT_BLKSZ, 0, &bdev); if (ret) { debug("Cannot create block device\n"); return ret; diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 20dc910d8a3..c39cd41aa38 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -906,7 +906,7 @@ int nvme_init(struct udevice *udev) /* The real blksz and size will be set by nvme_blk_probe() */ ret = blk_create_devicef(udev, "nvme-blk", name, UCLASS_NVME, - -1, 512, 0, &ns_udev); + -1, DEFAULT_BLKSZ, 0, &ns_udev); if (ret) goto free_id; |