From ed9d483a217ef7776bcb12fb7aa535339af9a4a8 Mon Sep 17 00:00:00 2001 From: YASUOKA Masahiko Date: Mon, 29 Jul 2019 14:51:40 +0000 Subject: Support disk write in efiboot. Requested by deraadt. --- sys/arch/amd64/stand/efiboot/efidev.c | 58 ++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 14 deletions(-) (limited to 'sys') diff --git a/sys/arch/amd64/stand/efiboot/efidev.c b/sys/arch/amd64/stand/efiboot/efidev.c index 47f62b92b96..e3ac1fe10ee 100644 --- a/sys/arch/amd64/stand/efiboot/efidev.c +++ b/sys/arch/amd64/stand/efiboot/efidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efidev.c,v 1.30 2018/08/10 16:41:35 jsing Exp $ */ +/* $OpenBSD: efidev.c,v 1.31 2019/07/29 14:51:39 yasuoka Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -104,19 +104,19 @@ efid_io(int rw, efi_diskinfo_t ed, u_int off, int nsect, void *buf) lba = (off + i_lblks) / blks; + /* allocate the space for reading unaligned blocks */ + if (ed->blkio->Media->BlockSize != DEV_BSIZE) { + if (iblk && iblksz < ed->blkio->Media->BlockSize) { + free(iblk, iblksz); + iblk = NULL; + } + if (iblk == NULL) { + iblk = alloc(ed->blkio->Media->BlockSize); + iblksz = ed->blkio->Media->BlockSize; + } + } switch (rw) { case F_READ: - /* allocate the space for reading unaligned blocks */ - if (ed->blkio->Media->BlockSize != DEV_BSIZE) { - if (iblk && iblksz < ed->blkio->Media->BlockSize) { - free(iblk, iblksz); - iblk = NULL; - } - if (iblk == NULL) { - iblk = alloc(ed->blkio->Media->BlockSize); - iblksz = ed->blkio->Media->BlockSize; - } - } if (i_lblks > 0) { status = EFI_CALL(ed->blkio->ReadBlocks, ed->blkio, ed->mediaid, lba - 1, @@ -147,8 +147,38 @@ efid_io(int rw, efi_diskinfo_t ed, u_int off, int nsect, void *buf) case F_WRITE: if (ed->blkio->Media->ReadOnly) goto on_eio; - /* XXX not yet */ - goto on_eio; + if (i_lblks > 0) { + status = EFI_CALL(ed->blkio->ReadBlocks, + ed->blkio, ed->mediaid, lba - 1, + ed->blkio->Media->BlockSize, iblk); + if (EFI_ERROR(status)) + goto on_eio; + memcpy(iblk + (blks - i_lblks) * DEV_BSIZE, buf, + min(nsect, i_lblks) * DEV_BSIZE); + status = EFI_CALL(ed->blkio->WriteBlocks, + ed->blkio, ed->mediaid, lba - 1, + ed->blkio->Media->BlockSize, iblk); + } + if (i_nblks > 0) { + status = EFI_CALL(ed->blkio->WriteBlocks, + ed->blkio, ed->mediaid, lba, + ed->blkio->Media->BlockSize * (i_nblks / blks), + buf + (i_lblks * DEV_BSIZE)); + if (EFI_ERROR(status)) + goto on_eio; + } + if (i_tblks > 0) { + status = EFI_CALL(ed->blkio->ReadBlocks, + ed->blkio, ed->mediaid, lba + (i_nblks / blks), + ed->blkio->Media->BlockSize, iblk); + if (EFI_ERROR(status)) + goto on_eio; + memcpy(iblk, buf + (i_lblks + i_nblks) * DEV_BSIZE, + i_tblks * DEV_BSIZE); + status = EFI_CALL(ed->blkio->WriteBlocks, + ed->blkio, ed->mediaid, lba + (i_nblks / blks), + ed->blkio->Media->BlockSize, iblk); + } break; } return (EFI_SUCCESS); -- cgit v1.2.3