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/d0baf98565a3
branches: trunk
changeset: 984086:d0baf98565a3
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 341b549a5b4a -r d0baf98565a3 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 @@
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 @@
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 @@
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 @@
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 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 @@
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 @@
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 @@
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 @@
}
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 @@
} 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 @@
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 @@
{
Home |
Main Index |
Thread Index |
Old Index