Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/stand/efiboot efiboot: Use disk I/O protocol for block d...



details:   https://anonhg.NetBSD.org/src/rev/aa991b75cbee
branches:  trunk
changeset: 379834:aa991b75cbee
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Mon Jun 21 11:11:33 2021 +0000

description:
efiboot: Use disk I/O protocol for block device access.

EFI_DISK_IO_PROTOCOL is a simplified interface to block devices. Use this
instead of EFI_BLOCK_IO_PROTOCOL for accessing block devices to simplify
the code -- we no longer need to worry about the underlying media's block
I/O size and alignment requirements.

diffstat:

 sys/stand/efiboot/efiblock.c |  183 +++++++++++++-----------------------------
 sys/stand/efiboot/efiblock.h |    3 +-
 sys/stand/efiboot/version    |    3 +-
 3 files changed, 60 insertions(+), 129 deletions(-)

diffs (truncated from 392 to 300 lines):

diff -r 237e7e52a258 -r aa991b75cbee sys/stand/efiboot/efiblock.c
--- a/sys/stand/efiboot/efiblock.c      Mon Jun 21 10:42:06 2021 +0000
+++ b/sys/stand/efiboot/efiblock.c      Mon Jun 21 11:11:33 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efiblock.c,v 1.12 2021/06/20 19:10:47 jmcneill Exp $ */
+/* $NetBSD: efiblock.c,v 1.13 2021/06/21 11:11:33 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -110,68 +110,41 @@ efi_block_generate_hash_mbr(struct efi_b
        MD5Final(bpart->hash, &md5ctx);
 }
 
-static void *
-efi_block_allocate_device_buffer(struct efi_block_dev *bdev, UINTN size,
-       void **buf_start)
+static EFI_STATUS
+efi_block_disk_read(struct efi_block_dev *bdev, UINT64 off, void *buf,
+    UINTN bufsize)
 {
-       void *buf;
-
-       if (bdev->bio->Media->IoAlign <= 1)
-               *buf_start = buf = AllocatePool(size);
-       else {
-               buf = AllocatePool(size + bdev->bio->Media->IoAlign - 1);
-               *buf_start = (buf == NULL) ? NULL :
-                   (void *)roundup2((intptr_t)buf, bdev->bio->Media->IoAlign);
-       }
-
-       return buf;
+       return uefi_call_wrapper(bdev->dio->ReadDisk, 5, bdev->dio,
+           bdev->media_id, off, bufsize, buf);
 }
 
 static int
 efi_block_find_partitions_cd9660(struct efi_block_dev *bdev)
 {
        struct efi_block_part *bpart;
-       struct iso_primary_descriptor *vd;
-       void *buf, *buf_start;
+       struct iso_primary_descriptor vd;
        EFI_STATUS status;
        EFI_LBA lba;
-       UINT32 sz;
-
-       if (bdev->bio->Media->BlockSize != DEV_BSIZE &&
-           bdev->bio->Media->BlockSize != ISO_DEFAULT_BLOCK_SIZE) {
-               return ENXIO;
-       }
-
-       sz = __MAX(sizeof(*vd), bdev->bio->Media->BlockSize);
-       sz = roundup(sz, bdev->bio->Media->BlockSize);
-       if ((buf = efi_block_allocate_device_buffer(bdev, sz, &buf_start)) == NULL) {
-               return ENOMEM;
-       }
 
        for (lba = 16;; lba++) {
-               status = uefi_call_wrapper(bdev->bio->ReadBlocks, 5,
-                   bdev->bio,
-                   bdev->media_id,
-                   lba * ISO_DEFAULT_BLOCK_SIZE / bdev->bio->Media->BlockSize,
-                   sz,
-                   buf_start);
+               status = efi_block_disk_read(bdev,
+                   lba * ISO_DEFAULT_BLOCK_SIZE, &vd, sizeof(vd));
                if (EFI_ERROR(status)) {
                        goto io_error;
                }
 
-               vd = (struct iso_primary_descriptor *)buf_start;
-               if (memcmp(vd->id, ISO_STANDARD_ID, sizeof vd->id) != 0) {
+               if (memcmp(vd.id, ISO_STANDARD_ID, sizeof vd.id) != 0) {
                        goto io_error;
                }
-               if (isonum_711(vd->type) == ISO_VD_END) {
+               if (isonum_711(vd.type) == ISO_VD_END) {
                        goto io_error;
                }
-               if (isonum_711(vd->type) == ISO_VD_PRIMARY) {
+               if (isonum_711(vd.type) == ISO_VD_PRIMARY) {
                        break;
                }
        }
 
-       if (isonum_723(vd->logical_block_size) != ISO_DEFAULT_BLOCK_SIZE) {
+       if (isonum_723(vd.logical_block_size) != ISO_DEFAULT_BLOCK_SIZE) {
                goto io_error;
        }
 
@@ -181,39 +154,29 @@ efi_block_find_partitions_cd9660(struct 
        bpart->type = EFI_BLOCK_PART_CD9660;
        TAILQ_INSERT_TAIL(&bdev->partitions, bpart, entries);
 
-       FreePool(buf);
        return 0;
 
 io_error:
-       FreePool(buf);
        return EIO;
 }
 
 static int
-efi_block_find_partitions_disklabel(struct efi_block_dev *bdev, struct mbr_sector *mbr, uint32_t start, uint32_t size)
+efi_block_find_partitions_disklabel(struct efi_block_dev *bdev,
+    struct mbr_sector *mbr, uint32_t start, uint32_t size)
 {
        struct efi_block_part *bpart;
+       char buf[DEV_BSIZE];
        struct disklabel d;
        struct partition *p;
        EFI_STATUS status;
-       EFI_LBA lba;
-       void *buf, *buf_start;
-       UINT32 sz;
        int n;
 
-       sz = __MAX(sizeof(d), bdev->bio->Media->BlockSize);
-       sz = roundup(sz, bdev->bio->Media->BlockSize);
-       if ((buf = efi_block_allocate_device_buffer(bdev, sz, &buf_start)) == NULL)
-               return ENOMEM;
-
-       lba = (((EFI_LBA)start + LABELSECTOR) * DEV_BSIZE) / bdev->bio->Media->BlockSize;
-       status = uefi_call_wrapper(bdev->bio->ReadBlocks, 5, bdev->bio, bdev->media_id,
-               lba, sz, buf_start);
-       if (EFI_ERROR(status) || getdisklabel(buf_start, &d) != NULL) {
+       status = efi_block_disk_read(bdev,
+           ((EFI_LBA)start + LABELSECTOR) * DEV_BSIZE, buf, sizeof(buf));
+       if (EFI_ERROR(status) || getdisklabel(buf, &d) != NULL) {
                FreePool(buf);
                return EIO;
        }
-       FreePool(buf);
 
        if (le32toh(d.d_magic) != DISKMAGIC || le32toh(d.d_magic2) != DISKMAGIC)
                return EINVAL;
@@ -254,23 +217,11 @@ efi_block_find_partitions_mbr(struct efi
        struct mbr_sector mbr;
        struct mbr_partition *mbr_part;
        EFI_STATUS status;
-       void *buf, *buf_start;
-       UINT32 sz;
        int n;
 
-       sz = __MAX(sizeof(mbr), bdev->bio->Media->BlockSize);
-       sz = roundup(sz, bdev->bio->Media->BlockSize);
-       if ((buf = efi_block_allocate_device_buffer(bdev, sz, &buf_start)) == NULL)
-               return ENOMEM;
-
-       status = uefi_call_wrapper(bdev->bio->ReadBlocks, 5, bdev->bio, bdev->media_id,
-               0, sz, buf_start);
-       if (EFI_ERROR(status)) {
-               FreePool(buf);
+       status = efi_block_disk_read(bdev, 0, &mbr, sizeof(mbr));
+       if (EFI_ERROR(status))
                return EIO;
-       }
-       memcpy(&mbr, buf_start, sizeof(mbr));
-       FreePool(buf);
 
        if (le32toh(mbr.mbr_magic) != MBR_MAGIC)
                return ENOENT;
@@ -280,7 +231,9 @@ efi_block_find_partitions_mbr(struct efi
                if (le32toh(mbr_part->mbrp_size) == 0)
                        continue;
                if (mbr_part->mbrp_type == MBR_PTYPE_NETBSD) {
-                       efi_block_find_partitions_disklabel(bdev, &mbr, le32toh(mbr_part->mbrp_start), le32toh(mbr_part->mbrp_size));
+                       efi_block_find_partitions_disklabel(bdev, &mbr,
+                           le32toh(mbr_part->mbrp_start),
+                           le32toh(mbr_part->mbrp_size));
                        break;
                }
        }
@@ -302,7 +255,8 @@ static const struct {
 };
 
 static int
-efi_block_find_partitions_gpt_entry(struct efi_block_dev *bdev, struct gpt_hdr *hdr, struct gpt_ent *ent, UINT32 index)
+efi_block_find_partitions_gpt_entry(struct efi_block_dev *bdev,
+    struct gpt_hdr *hdr, struct gpt_ent *ent, UINT32 index)
 {
        struct efi_block_part *bpart;
        uint8_t fstype = FS_UNUSED;
@@ -311,7 +265,8 @@ efi_block_find_partitions_gpt_entry(stru
 
        memcpy(&uuid, ent->ent_type, sizeof(uuid));
        for (n = 0; n < __arraycount(gpt_guid_to_str); n++)
-               if (memcmp(ent->ent_type, &gpt_guid_to_str[n].guid, sizeof(ent->ent_type)) == 0) {
+               if (memcmp(ent->ent_type, &gpt_guid_to_str[n].guid,
+                   sizeof(ent->ent_type)) == 0) {
                        fstype = gpt_guid_to_str[n].fstype;
                        break;
                }
@@ -340,42 +295,35 @@ efi_block_find_partitions_gpt(struct efi
        struct gpt_hdr hdr;
        struct gpt_ent ent;
        EFI_STATUS status;
-       void *buf, *buf_start;
-       UINT32 sz, entry;
+       UINT32 entry;
+       void *buf;
+       UINTN sz;
 
-       sz = __MAX(sizeof(hdr), bdev->bio->Media->BlockSize);
-       sz = roundup(sz, bdev->bio->Media->BlockSize);
-       if ((buf = efi_block_allocate_device_buffer(bdev, sz, &buf_start)) == NULL)
-               return ENOMEM;
-
-       status = uefi_call_wrapper(bdev->bio->ReadBlocks, 5, bdev->bio, bdev->media_id,
-               GPT_HDR_BLKNO, sz, buf_start);
+       status = efi_block_disk_read(bdev, GPT_HDR_BLKNO * DEV_BSIZE, &hdr,
+           sizeof(hdr));
        if (EFI_ERROR(status)) {
-               FreePool(buf);
                return EIO;
        }
-       memcpy(&hdr, buf_start, sizeof(hdr));
-       FreePool(buf);
 
        if (memcmp(hdr.hdr_sig, GPT_HDR_SIG, sizeof(hdr.hdr_sig)) != 0)
                return ENOENT;
        if (le32toh(hdr.hdr_entsz) < sizeof(ent))
                return EINVAL;
 
-       sz = __MAX(le32toh(hdr.hdr_entsz) * le32toh(hdr.hdr_entries), bdev->bio->Media->BlockSize);
-       sz = roundup(sz, bdev->bio->Media->BlockSize);
-       if ((buf = efi_block_allocate_device_buffer(bdev, sz, &buf_start)) == NULL)
+       sz = le32toh(hdr.hdr_entsz) * le32toh(hdr.hdr_entries);
+       buf = AllocatePool(sz);
+       if (buf == NULL)
                return ENOMEM;
 
-       status = uefi_call_wrapper(bdev->bio->ReadBlocks, 5, bdev->bio, bdev->media_id,
-               le64toh(hdr.hdr_lba_table), sz, buf_start);
+       status = efi_block_disk_read(bdev,
+           le64toh(hdr.hdr_lba_table) * DEV_BSIZE, buf, sz);
        if (EFI_ERROR(status)) {
                FreePool(buf);
                return EIO;
        }
 
        for (entry = 0; entry < le32toh(hdr.hdr_entries); entry++) {
-               memcpy(&ent, buf_start + (entry * le32toh(hdr.hdr_entsz)),
+               memcpy(&ent, buf + (entry * le32toh(hdr.hdr_entsz)),
                        sizeof(ent));
                efi_block_find_partitions_gpt_entry(bdev, &hdr, &ent, entry);
        }
@@ -405,6 +353,7 @@ efi_block_probe(void)
        struct efi_block_dev *bdev;
        struct efi_block_part *bpart;
        EFI_BLOCK_IO *bio;
+       EFI_DISK_IO *dio;
        EFI_STATUS status;
        uint16_t devindex = 0;
        int depth = -1;
@@ -423,16 +372,23 @@ efi_block_probe(void)
        }
 
        for (n = 0; n < efi_nblock; n++) {
-               status = uefi_call_wrapper(BS->HandleProtocol, 3, efi_block[n], &BlockIoProtocol, (void **)&bio);
+               status = uefi_call_wrapper(BS->HandleProtocol, 3, efi_block[n],
+                   &BlockIoProtocol, (void **)&bio);
                if (EFI_ERROR(status) || !bio->Media->MediaPresent)
                        continue;
 
                if (bio->Media->LogicalPartition)
                        continue;
 
+               status = uefi_call_wrapper(BS->HandleProtocol, 3, efi_block[n],
+                   &DiskIoProtocol, (void **)&dio);
+               if (EFI_ERROR(status))
+                       continue;
+
                bdev = alloc(sizeof(*bdev));
                bdev->index = devindex++;
                bdev->bio = bio;
+               bdev->dio = dio;
                bdev->media_id = bio->Media->MediaId;
                bdev->path = DevicePathFromHandle(efi_block[n]);
                TAILQ_INIT(&bdev->partitions);
@@ -529,7 +485,7 @@ efi_block_show(void)
                                } else {
                                        Print(L"\"%s\"", bpart->gpt.ent.ent_name);
                                }
-                       
+
                                /* Size in MB */
                                size = (le64toh(bpart->gpt.ent.ent_lba_end) - le64toh(bpart->gpt.ent.ent_lba_start)) * bdev->bio->Media->BlockSize;
                                size /= (1024 * 1024);
@@ -565,7 +521,7 @@ efi_block_open(struct open_file *f, ...)
        char *path;
        va_list ap;
        int rv, n;
-       
+
        va_start(ap, f);
        fname = va_arg(ap, const char *);
        file = va_arg(ap, char **);
@@ -603,7 +559,7 @@ efi_block_strategy(void *devdata, int rw
 {



Home | Main Index | Thread Index | Old Index