grub-devel.gnu.org archive mirror
 help / color / mirror / Atom feed
From: Mate Kukri <mate.kukri@canonical.com>
To: grub-devel@gnu.org
Cc: David F <davidf@terabyteunlimited.com>,
	Mate Kukri <mate.kukri@canonical.com>
Subject: [PATCH] efidisk: Breakup large reads into batches
Date: Fri, 23 Feb 2024 16:53:37 +0000	[thread overview]
Message-ID: <20240223165336.252125-1-mate.kukri@canonical.com> (raw)

From: David F <davidf@terabyteunlimited.com>

Work around firmware bugs that cause large reads to fail from certain
devices.

Report-By: David F <davidf@terabyteunlimited.com>
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
---
 grub-core/disk/efi/efidisk.c | 43 +++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
index 3b5ed5691..079b72ab7 100644
--- a/grub-core/disk/efi/efidisk.c
+++ b/grub-core/disk/efi/efidisk.c
@@ -27,6 +27,9 @@
 #include <grub/efi/efi.h>
 #include <grub/efi/disk.h>
 
+/* break up io to prevent problems under some UEFI envrionments */
+#define EFIDISK_C_MAXIOSECS 0x100U
+
 struct grub_efidisk_data
 {
   grub_efi_handle_t handle;
@@ -599,20 +602,34 @@ grub_efidisk_read (struct grub_disk *disk, grub_disk_addr_t sector,
 		   grub_size_t size, char *buf)
 {
   grub_efi_status_t status;
+  grub_size_t sector_count;
 
-  grub_dprintf ("efidisk",
-		"reading 0x%lx sectors at the sector 0x%llx from %s\n",
-		(unsigned long) size, (unsigned long long) sector, disk->name);
-
-  status = grub_efidisk_readwrite (disk, sector, size, buf, 0);
-
-  if (status == GRUB_EFI_NO_MEDIA)
-    return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name);
-  else if (status != GRUB_EFI_SUCCESS)
-    return grub_error (GRUB_ERR_READ_ERROR,
-		       N_("failure reading sector 0x%llx from `%s'"),
-		       (unsigned long long) sector,
-		       disk->name);
+  /* break up reads to EFIDISK_C_MAXIOSECS size chunks */
+  do
+    {
+      /* determine number of sectors this cycle */
+      sector_count = (size > EFIDISK_C_MAXIOSECS) ? EFIDISK_C_MAXIOSECS : size;
+
+      /* output debug information */
+      grub_dprintf ("efidisk",
+		    "reading 0x%lx sectors at the sector 0x%llx from %s\n",
+		    (unsigned long) sector_count, (unsigned long long) sector, disk->name);
+
+      status = grub_efidisk_readwrite (disk, sector, sector_count, buf, 0);
+
+      if (status == GRUB_EFI_NO_MEDIA)
+	return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("no media in `%s'"), disk->name);
+      if (status != GRUB_EFI_SUCCESS)
+	return grub_error (GRUB_ERR_READ_ERROR,
+			   N_("failure reading 0x%lx sector(s) from sector 0x%llx on `%s'"),
+			   (unsigned long) sector_count, (unsigned long long) sector, disk->name);
+
+      /* next cycle */
+      buf += (grub_efi_uintn_t) sector_count << disk->log_sector_size;;
+      sector += sector_count;
+      size -= sector_count;
+    }
+  while (size);
 
   return GRUB_ERR_NONE;
 }
-- 
2.39.2


_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

             reply	other threads:[~2024-02-23 17:12 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-23 16:53 Mate Kukri [this message]
2024-02-23 17:28 ` [PATCH] efidisk: Breakup large reads into batches Vladimir 'phcoder' Serbinenko
2024-02-23 21:29 ` Olaf Hering

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240223165336.252125-1-mate.kukri@canonical.com \
    --to=mate.kukri@canonical.com \
    --cc=davidf@terabyteunlimited.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).