Blame SOURCES/0165-efinet-handle-get_status-on-buggy-firmware-properly.patch

f725e3
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
f725e3
From: Josef Bacik <jbacik@fb.com>
f725e3
Date: Thu, 6 Aug 2015 10:49:46 -0700
f725e3
Subject: [PATCH] efinet: handle get_status() on buggy firmware properly
f725e3
f725e3
The EFI spec indicates that get_status() should return the address of the buffer
f725e3
we passed into transmit to indicate the the buffer was transmitted.  However we
f725e3
have boxes where the firmware returns some arbitrary address instead, which
f725e3
makes grub think that we've not sent anything.  So since we have the SNP stuff
f725e3
opened in exclusive mode just assume any non-NULL txbuf means that our transmit
f725e3
occurred properly.  This makes grub able to do its networking stuff properly on
f725e3
our broken firmware.  Thanks,
f725e3
f725e3
cc: Peter Jones <pjones@redhat.com>
f725e3
Signed-off-by: Josef Bacik <jbacik@fb.com>
f725e3
---
f725e3
 grub-core/net/drivers/efi/efinet.c | 21 +++++++++++----------
f725e3
 1 file changed, 11 insertions(+), 10 deletions(-)
f725e3
f725e3
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
f725e3
index 7b8c4a59d10..ea0e0ca360e 100644
f725e3
--- a/grub-core/net/drivers/efi/efinet.c
f725e3
+++ b/grub-core/net/drivers/efi/efinet.c
f725e3
@@ -47,19 +47,19 @@ send_card_buffer (struct grub_net_card *dev,
f725e3
 	if (st != GRUB_EFI_SUCCESS)
f725e3
 	  return grub_error (GRUB_ERR_IO,
f725e3
 			     N_("couldn't send network packet"));
f725e3
-	if (txbuf == dev->txbuf)
f725e3
+	/*
f725e3
+	   Some buggy firmware could return an arbitrary address instead of the
f725e3
+	   txbuf address we trasmitted, so just check that txbuf is non NULL
f725e3
+	   for success.  This is ok because we open the SNP protocol in
f725e3
+	   exclusive mode so we know we're the only ones transmitting on this
f725e3
+	   box and since we only transmit one packet at a time we know our
f725e3
+	   transmit was successfull.
f725e3
+	 */
f725e3
+	if (txbuf)
f725e3
 	  {
f725e3
 	    dev->txbusy = 0;
f725e3
 	    break;
f725e3
 	  }
f725e3
-	if (txbuf)
f725e3
-	  {
f725e3
-	    st = efi_call_7 (net->transmit, net, 0, dev->last_pkt_size,
f725e3
-			     dev->txbuf, NULL, NULL, NULL);
f725e3
-	    if (st != GRUB_EFI_SUCCESS)
f725e3
-	      return grub_error (GRUB_ERR_IO,
f725e3
-				 N_("couldn't send network packet"));
f725e3
-	  }
f725e3
 	if (limit_time < grub_get_time_ms ())
f725e3
 	  return grub_error (GRUB_ERR_TIMEOUT,
f725e3
 			     N_("couldn't send network packet"));
f725e3
@@ -84,8 +84,9 @@ send_card_buffer (struct grub_net_card *dev,
f725e3
      we run in the GRUB_ERR_TIMEOUT case above.
f725e3
      Perhaps a timeout in the FW has discarded the recycle buffer.
f725e3
    */
f725e3
+  txbuf = NULL;
f725e3
   st = efi_call_3 (net->get_status, net, 0, &txbuf);
f725e3
-  dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf == dev->txbuf);
f725e3
+  dev->txbusy = !(st == GRUB_EFI_SUCCESS && txbuf);
f725e3
 
f725e3
   return GRUB_ERR_NONE;
f725e3
 }