dcavalca / rpms / grub2

Forked from rpms/grub2 3 years ago
Clone

Blame SOURCES/0158-efinet-Check-for-immediate-completition.patch

28f7f8
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
ecb9bb
From: Martin Wilck <martin.wilck@ts.fujitsu.com>
ecb9bb
Date: Fri, 27 Mar 2015 14:27:56 +0100
28f7f8
Subject: [PATCH] efinet: Check for immediate completition.
ecb9bb
ecb9bb
This both speeds GRUB up and workarounds unexpected EFI behaviour.
ecb9bb
---
ecb9bb
 grub-core/net/drivers/efi/efinet.c | 16 ++++++++++++++--
ecb9bb
 1 file changed, 14 insertions(+), 2 deletions(-)
ecb9bb
ecb9bb
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
28f7f8
index a6e4c7992f7..78df215be12 100644
ecb9bb
--- a/grub-core/net/drivers/efi/efinet.c
ecb9bb
+++ b/grub-core/net/drivers/efi/efinet.c
ecb9bb
@@ -37,11 +37,12 @@ send_card_buffer (struct grub_net_card *dev,
ecb9bb
   grub_efi_status_t st;
ecb9bb
   grub_efi_simple_network_t *net = dev->efi_net;
ecb9bb
   grub_uint64_t limit_time = grub_get_time_ms () + 4000;
ecb9bb
+  void *txbuf;
ecb9bb
 
ecb9bb
   if (dev->txbusy)
ecb9bb
     while (1)
ecb9bb
       {
ecb9bb
-	void *txbuf = NULL;
ecb9bb
+	txbuf = NULL;
ecb9bb
 	st = efi_call_3 (net->get_status, net, 0, &txbuf);
ecb9bb
 	if (st != GRUB_EFI_SUCCESS)
ecb9bb
 	  return grub_error (GRUB_ERR_IO,
ecb9bb
@@ -74,7 +75,18 @@ send_card_buffer (struct grub_net_card *dev,
ecb9bb
 		   dev->txbuf, NULL, NULL, NULL);
ecb9bb
   if (st != GRUB_EFI_SUCCESS)
ecb9bb
     return grub_error (GRUB_ERR_IO, N_("couldn't send network packet"));
ecb9bb
-  dev->txbusy = 1;
ecb9bb
+
ecb9bb
+  /*
ecb9bb
+     The card may have sent out the packet immediately - set txbusy
ecb9bb
+     to 0 in this case.
ecb9bb
+     Cases were observed where checking txbuf at the next call
ecb9bb
+     of send_card_buffer() is too late: 0 is returned in txbuf and
ecb9bb
+     we run in the GRUB_ERR_TIMEOUT case above.
ecb9bb
+     Perhaps a timeout in the FW has discarded the recycle buffer.
ecb9bb
+   */
ecb9bb
+  st = efi_call_3 (net->get_status, net, 0, &txbuf);
ecb9bb
+  dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf);
ecb9bb
+
ecb9bb
   return GRUB_ERR_NONE;
ecb9bb
 }
ecb9bb