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

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