Sync efid_io() with the recent improvements kettenis@ made to
authorkrw <krw@openbsd.org>
Thu, 10 Jun 2021 18:06:35 +0000 (18:06 +0000)
committerkrw <krw@openbsd.org>
Thu, 10 Jun 2021 18:06:35 +0000 (18:06 +0000)
arm64 efid_io().

ok kettenis@

sys/arch/armv7/stand/efiboot/efidev.c

index 2e6bdbf..7902778 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: efidev.c,v 1.8 2021/06/07 21:18:31 krw Exp $  */
+/*     $OpenBSD: efidev.c,v 1.9 2021/06/10 18:06:35 krw Exp $  */
 
 /*
  * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -74,41 +74,57 @@ efid_init(struct diskinfo *dip, void *handle)
 static EFI_STATUS
 efid_io(int rw, efi_diskinfo_t ed, u_int off, int nsect, void *buf)
 {
-       EFI_STATUS status = EFI_SUCCESS;
+       u_int blks, start, end;
        EFI_PHYSICAL_ADDRESS addr;
+       EFI_STATUS status;
        caddr_t data;
+       size_t size;
 
-       if (ed->blkio->Media->BlockSize != DEV_BSIZE)
+       /* block count of the intrinsic block size in DEV_BSIZE */
+       blks = EFI_BLKSPERSEC(ed);
+       if (blks == 0)
+               /* block size < 512.  HP Stream 13 actually has such a disk. */
                return (EFI_UNSUPPORTED);
 
+       start = off / blks;
+       end = (off + nsect + blks - 1) / blks;
+       size = (end - start) * ed->blkio->Media->BlockSize;
+
        status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
-           EFI_SIZE_TO_PAGES(nsect * DEV_BSIZE), &addr);
+           EFI_SIZE_TO_PAGES(size), &addr);
        if (EFI_ERROR(status))
                goto on_eio;
        data = (caddr_t)(uintptr_t)addr;
 
        switch (rw) {
        case F_READ:
-               status = ed->blkio->ReadBlocks(ed->blkio, ed->mediaid, off,
-                   nsect * DEV_BSIZE, data);
+               status = ed->blkio->ReadBlocks(ed->blkio, ed->mediaid, start,
+                   size, data);
                if (EFI_ERROR(status))
                        goto on_eio;
-               memcpy(buf, data, nsect * DEV_BSIZE);
+               memcpy(buf, data + DEV_BSIZE * (off - start * blks),
+                   DEV_BSIZE * nsect);
                break;
        case F_WRITE:
                if (ed->blkio->Media->ReadOnly)
                        goto on_eio;
-               memcpy(data, buf, nsect * DEV_BSIZE);
-               status = ed->blkio->WriteBlocks(ed->blkio, ed->mediaid, off,
-                   nsect * DEV_BSIZE, data);
+               if (off % blks != 0 || nsect % blks != 0) {
+                       status = ed->blkio->ReadBlocks(ed->blkio, ed->mediaid,
+                           start, size, data);
+                       if (EFI_ERROR(status))
+                               goto on_eio;
+               }
+               memcpy(data + DEV_BSIZE * (off - start * blks), buf,
+                   DEV_BSIZE * nsect);
+               status = ed->blkio->WriteBlocks(ed->blkio, ed->mediaid, start,
+                   size, data);
                if (EFI_ERROR(status))
                        goto on_eio;
                break;
        }
-       return (EFI_SUCCESS);
 
 on_eio:
-       BS->FreePages(addr, EFI_SIZE_TO_PAGES(nsect * DEV_BSIZE));
+       BS->FreePages(addr, EFI_SIZE_TO_PAGES(size));
 
        return (status);
 }