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